WoW voice chat versus Mullvad on Linux
I play World of Warcraft on Linux, through Battle.net running under umu-run with GE-Proton. It mostly just works. Two things didn’t: a voice chat error that popped up every 30 seconds, and a launch that took forever. Both turned out to be the same bug, and the culprit wasn’t Wine or Blizzard. It was my VPN’s firewall.
The symptoms
Every 30 seconds the chat window showed me:
Lost connection to the voice chat service (VoiceError: 17)
On top of that, hitting Play took 1.5 to 2.5 minutes before the game window showed up. I’d initially assumed that was just a Wine issue. After the fix it takes about 20 seconds.
What’s actually going on
The Blizzard client and its voice proxy (Utils/WowVoiceProxyT.exe) use a trick to wake up their own threads: they open a TCP socket on loopback and connect it to itself. Writing a byte to it wakes up whatever thread is waiting on the other end.
Both directions of the flow share the exact same address. Linux’s connection tracking (conntrack) follows TCP sequence numbers and windows per direction, and with both directions looking identical it gets confused. The first segment goes through. Every segment after that gets marked INVALID.
Normally that’s harmless, because nothing drops invalid packets on loopback. Mullvad’s nftables rules do drop them. So:
- The voice proxy never wakes up to accept the game’s connection. The game gives up, retries, and 30 seconds later we get VoiceError 17 again.
- The game’s own network thread stalls in the same way, until some retransmit happens to slip through. I suspect this causes the slow launch.
Reproducing it without the game
This can be tested without WoW. A self-connected socket in Python:
import socket
s = socket.socket()
s.bind(("127.0.0.1", 0))
s.connect(s.getsockname())
s.settimeout(3)
for i in (1, 2):
s.send(b"x")
try:
print(i, s.recv(1))
except TimeoutError:
print(i, "dropped")
With Mullvad connected, the first send arrives and the second doesn’t. The invalid counter in /proc/net/stat/nf_conntrack climbs.
The fix
Set conntrack to be liberal about TCP window tracking:
echo 'net.netfilter.nf_conntrack_tcp_be_liberal = 1' | sudo tee /etc/sysctl.d/99-conntrack-liberal.conf
sudo sysctl --system
With nf_conntrack_tcp_be_liberal set, conntrack only marks out-of-window RST segments as invalid, so the self-connected socket’s traffic stops being dropped. Voice chat connects and the game launches in about 20 seconds.
Not just Mullvad
There are Blizzard and Lutris forum threads blaming firewalld for the same VoiceError. Any firewall that drops ctstate invalid will cause the issue this resolves.