Field note: a dying Switchvox appliance, a Hyper-V rebuild, and the 32-second drops that weren't the hardware
A Switchvox box with a failing network port got moved to a Hyper-V VM in an afternoon. The calls kept dropping at 32 seconds anyway, and a packet capture showed the real cause was one empty setting.
Updated the day after publishing. The first version of this note blamed the failing network port for the calls dropping at 32 seconds. That was wrong. The port really was failing and the move to a VM was still the right call, but the 32-second drops had a separate cause that had been there all along. Both stories are below, because the second one is the more useful lesson.
The complaint was the usual one: “the phones stopped working, then started again,” plus calls cutting off mid-conversation. Two things turned out to be wrong, stacked on top of each other. The Switchvox appliance’s network port was quietly corrupting incoming traffic, and the PBX was missing one setting for a second office subnet. I fixed the first one and assumed that was the whole story. It wasn’t.
Problem one: the appliance’s network port was failing
Switchvox doesn’t give you a shell, but Server > Server Information > Advanced Server Information includes the ifconfig output. On eth0 the receive side showed tens of thousands of RX errors and frame errors, still climbing. The transmit side was clean. Frame errors on receive mean frames are arriving damaged, which points at the physical layer.
I ruled things out one at a time:
- Rebooted the PBX. The counters reset and started climbing again within minutes.
- Checked the switch port. 1 Gbps full duplex, almost no errors on the switch side. The switch was sending clean frames.
- Replaced the patch cable and moved to a different switch port. The errors kept coming.
That left the appliance’s own port. An RMA takes days, and the office already had a Hyper-V host with room to spare, so I rebuilt the phone system as a VM the same afternoon.
The rebuild, briefly
- Full backup first under Server > Maintenance: Backups, with voicemail, greetings and music on hold included. Sangoma says creating a backup shouldn’t affect calls in progress.
- Match the version exactly. Sangoma’s newest published Hyper-V image was older than what the appliance ran, and a backup won’t restore onto an older version. I installed the matching release from Sangoma’s ISO into a Generation 2 VM with Secure Boot off. Sangoma lists those ISOs for appliances, not VMs, so treat that as “worked for me.” Verify the ISO’s MD5 checksum (listed next to it on the downloads page) before you use it.
- Build it for voice: fixed memory, a CPU reservation, and a higher CPU weight so busy neighbors can’t starve it. The 2 vCPUs below suit a small office. For scale, Sangoma’s benchmark for Switchvox 8.x is 4 vCPUs and 8 GB of RAM for 150 phones and 45 concurrent calls.
$n = 'Switchvox'
New-VM -Name $n -Generation 2 -MemoryStartupBytes 8GB -Path 'D:\VMs' `
-NewVHDPath "D:\VMs\$n\Switchvox.vhdx" -NewVHDSizeBytes 100GB -SwitchName 'YourVMSwitch'
Set-VM $n -StaticMemory -ProcessorCount 2 -AutomaticStartAction Nothing
Set-VMProcessor $n -Reserve 50 -RelativeWeight 200
Add-VMDvdDrive -VMName $n -Path 'D:\ISO\Switchvox.iso'
Set-VMFirmware $n -EnableSecureBoot Off -FirstBootDevice (Get-VMDvdDrive -VMName $n)
Once the install finished, I ejected the ISO and put the disk first in the boot order. Otherwise the next reboot lands back in the installer, and it starts on its own after a countdown.
Get-VMDvdDrive -VMName $n | Set-VMDvdDrive -Path $null
Set-VMFirmware $n -FirstBootDevice (Get-VMHardDiskDrive -VMName $n)
- Cut over in order: take a final backup, release the license on the old box, shut it down and keep it off (only one production system per registration code), register the VM under Server > Maintenance: Registration, restore the backup under Server > Maintenance: Backups (Upload & Restore Backup) with Restore Custom SSL Certificates and Overwrite Server UUID on, then give the VM the old IP. If you use Sangoma-brand phones, Sangoma recommends rebooting them after the restore so they reconnect cleanly. If the restore upload spins with no percentage, the browser upload stalled. Close it and upload again.
Afterward the VM showed zero receive errors and trunk latency dropped from over 100 ms to single digits. I called it fixed.
Problem two: the drops came back the next day
The next afternoon a ticket came in: calls dropping again. The VM’s interface counters were still at zero, so this wasn’t the hardware.
What it looked like
I pulled the call log and sorted by talk time. The dropped calls had a very clear pattern:
- Every one ended at 30 to 32 seconds of talk time.
- Every one was placed from a phone on the second site’s subnet. That site reaches the main office over a routed link, so its phones sit on a different subnet from the PBX.
- Calls into those same phones, from outside or from the main office, ran for minutes.
- Calls placed from main-office phones were fine.
Then I checked the log from the morning before the migration, when the old appliance was still running. Same pattern. This had nothing to do with the hardware or the move. It had been there all along, hidden under the NIC problem.
Why 32 seconds points at a lost ACK
When a phone places a call and the far end answers, the PBX sends a 200 OK, and the phone confirms it with an ACK. If the ACK never arrives, the PBX keeps resending the 200 OK and gives up after 64 × T1. T1 defaults to 500 ms, so that’s 32 seconds, and then the call gets torn down.
That also explains the direction. On calls into the remote phones, the PBX is the one sending the ACK, so nothing goes missing.
Finding it with a packet capture
Firewall rules, routes and the remote router’s NAT all looked right. So I ran a packet capture on the firewall interface facing the second site, filtered to one of its phones on UDP 5060, and had that phone make a test call. It dropped at 32 seconds. The capture showed exactly why:
PBX -> phone SIP/2.0 200 OK CSeq: 8119 INVITE Contact: <sip:203.0.113.10:5060>
PBX -> phone 200 OK (retransmit) ...every 1-4 seconds...
PBX -> phone 200 OK (last retransmit, ~32 s after the first)
PBX -> phone BYE
(The public address is replaced with a documentation example.)
The Contact header in the PBX’s answer carried the office’s public IP, not the PBX’s private address. The phone did what the spec tells it to and sent its ACK to that public address. The ACK headed toward the internet side of the firewall and never came back in to the PBX.
The cause: one empty field
The PBX has NAT support turned on, with the office’s external IP filled in, so remote phones and the SIP trunk work. With that on, Switchvox treats only its own subnet as local and uses the external IP for everything else. The second site’s subnet wasn’t listed anywhere as local, so the PBX treated those phones like they were out on the internet.
The phone-network mapping for that subnet was already set up correctly, and it didn’t prevent this.
The fix
Under Server > IP Configuration, in Advanced Options, I added the second site’s subnet to Additional Local Networks. Sangoma describes the field as the place to list networks that reach the PBX without going through a NATing router, such as a remote office, so their phones use the PBX’s private address. The field takes CIDR or netmask notation. Saving the IP configuration restarts the PBX’s networking and drops any active calls, so I checked Server > Current Calls first. It was empty.
After a couple of minutes everything re-registered. The same phone that had dropped at 32 seconds made a test call that ran past a minute. So did the call from the original ticket.
What I took away from it
- Two problems can hide behind one symptom. Fixing the obvious hardware fault made me stop looking. Check the call log from before your fix to see whether the pattern really changed.
- 32 seconds on the dot means a lost ACK. Before touching hardware, sort dropped calls by talk time and by who placed the call.
- Every routed phone subnet belongs in Additional Local Networks whenever NAT support is on, meaning any subnet that reaches the PBX without being NATed. Being in the phone-network mapping isn’t enough.
- Test calls from every subnet, and in both directions. My checklist after the migration said “hold one call past 32 seconds” but didn’t say from where. From the main office, that test passes every time.
- A 30-second firewall packet capture beats an afternoon of guessing. The
Contactheader in the 200 OK told the whole story.
Sources
- RFC 3261: SIP: 2xx retransmission and the 64×T1 limit (13.3.1.4), T1’s 500 ms default (Appendix A), and the ACK for a 2xx going to the remote target from the Contact header (12.1.2, 13.2.2.4)
- Sangoma: Can I use Switchvox in a virtualized environment?: supported hypervisors, Gen 2 VMs, the Silver subscription exclusion, the backup-restore migration path, and sizing benchmarks
- Sangoma: Switchvox downloads: Hyper-V images and DVD ISOs for each release, with MD5 checksums
- Sangoma: How to replace a Switchvox appliance and software: same registration code, same version, same IP, then restore; backups shouldn’t affect calls in progress; reboot Sangoma phones afterward
- Sangoma: How to unregister your Switchvox PBX
- Sangoma: Switchvox networking, IP Configuration: what Additional Local Networks is for (networks not separated from the PBX by NAT, such as a remote office) and when it’s needed
- Microsoft Learn: New-VM, Set-VM, Set-VMProcessor, Set-VMFirmware, Set-VMDvdDrive
From Small Town Sysadmin
Get new guides by email
Plain-English tech tips, scam and security alerts, and fixes for small offices, whether you're the office manager or the IT pro. No spam, and you can unsubscribe anytime.