I think your precedence setting is misconfigured.
::ffff:0:0/96 matches for IPv6 transition mechanisms like NAT64/DNS64, not the entire IPv6 address space. It looks like you have working IPv6 so this precedence isn't being applied to it because it is not included in that range.
I think setting the following should set Steam to prefer IPv4 over IPv6.
precedence ::/0 100
Give that a try and let me know if that helps!
Edit: This should set IPv4 to be the preferred protocol for ALL communications on your server, not just to steam. Keep that in mind.
At section 10.3, RFC 3484 says:
The default policy table gives IPv6 addresses higher precedence than
IPv4 addresses. This means that applications will use IPv6 in
preference to IPv4 when the two are equally suitable. An
administrator can change the policy table to prefer IPv4 addresses by
giving the ::ffff:0.0.0.0/96 prefix a higher precedence
This is also what is commented in /etc/gai.conf:
# For sites which prefer IPv4 connections change the last line to
#
#precedence ::ffff:0:0/96 100
i dont use steam but i do confirm that only uncommenting:
precedence ::ffff:0:0/96 100
makes my machines prefer ip4 over ip6 for all of the internet, and i also have working ipv6 natively.
Can confirm this still happens. This is a problem for me as I use an IPv6-only VPN for access to IPv6 services, and the speed of downloads on Steam through it are incredibly slow compared to my IPv4 connection. I shouldn't have to disconnect from it just to update a game, as that will interrupt other things I have running that access services on IPv6.
This would be an even bigger problem for people using tunnels that actually limit bandwidth and data transferred.
I'm also experiencing that the steam client does not respect the preference for IPv4 in gai.conf as reported by others before. Steam should respect the settings of the operating system, so I consider this a bug.
There is a workaround to force steam to use IPv4 by starting steam in a network namespace that only has IPv4.
sudo ip netns add ipv4_onlysudo ip link add macvlan0 link $network_interface type macvlan mode bridgesudo ip link set macvlan0 netns ipv4_onlysudo ip netns exec ipv4_only ip link set lo upsudo ip netns exec ipv4_only dhclientsudo ip netns exec ipv4_only sysctl set net.ipv6.conf.macvlan0.disable_ipv6=1sudo ip netns exec ipv4_only sudo -u $user /usr/games/steamMaybe I'll find time to automate this with systemd or some custom launcher for steam. Any ideas how to achieve that are appreciated.
I don't have anything else to add besides what was originally said, but I want to say that this issue is present for me too.
Adding some findings and a workaround that is scoped to Steam alone. No routing changes, no network namespace, no system-wide DNS or gai.conf changes, absolutely nothing that should affect other applications.
Result on my system: ~36 Mbps → ~900 Mbps on symmetric gigabit fiber. Store, friends, overlay, steam:// handlers, native games and Proton games were tested and all continue to work.
1. The client has a cvar for this. It is already 0, and it is ignored.
In the Steam console (steam://open/console):
] find HTTPPlatform
@nClientEnableIPv6ForHTTPPlatformWindows = "0" - Enable IPv6 HTTP connections by default on Windows clients
@nClientEnableIPv6ForHTTPPlatformLinux = "0" - Enable IPv6 HTTP connections by default on Linux clients
The Linux cvar exists and defaults to 0, yet content downloads still go over IPv6. Setting it explicitly in steam_dev.cfg changes nothing (unsurprisingly, it was already 0). Whatever this setting controls, it is not the content download path, or it is being overridden.
2. Steam does use NSS. Pinning cacheN-<region>1.steamcontent.com entries in /etc/hosts to their A records worked: content connections switched to ::ffff: IPv4-mapped addresses immediately. So the client is not bypassing the resolver stack; it goes through getaddrinfo() and only disregards the RFC 3484/6724 precedence sorting that gai.conf configures. That distinction is what makes the workaround below possible.
3. glibc's no-aaaa resolver option is the right lever, and it is settable per-process via RES_OPTIONS (glibc 2.36+). If the resolver never returns a AAAA record, there is nothing for the client to prefer.
4. On systemd-resolved systems, RES_OPTIONS never reaches glibc. With the common nsswitch.conf line:
hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns
nss-resolve hands lookups to systemd-resolved over D-Bus before glibc's stub resolver is involved, so RES_OPTIONS=no-aaaa is silently ignored. This is the only thing standing between the per-process fix and working out of the box.
If grep '^hosts:' /etc/nsswitch.conf shows files dns (no resolve), you need nothing else:
env RES_OPTIONS=no-aaaa steam
Give Steam (and only Steam) an nsswitch.conf without nss-resolve, using a bind mount in a mount namespace. bubblewrap should already installed on any system with Steam, since the Steam runtime uses it itself.
Create /etc/steam-nsswitch.conf as a copy of your system nsswitch.conf with resolve [!UNAVAIL=return] removed from the hosts: line:
# Copy of /etc/nsswitch.conf with nss-resolve removed from the hosts line,
# so that glibc's stub resolver (which honours RES_OPTIONS) is used instead.
hosts: mymachines files myhostname dns
Important note: Keep the rest of your own file's hosts: entries as they are. mymachines and myhostname matter, don't drop them.
Then launch:
bwrap --dev-bind / / \
--bind /etc/steam-nsswitch.conf /etc/nsswitch.conf \
--setenv RES_OPTIONS no-aaaa \
/usr/bin/steam
--dev-bind / / passes the entire system through unchanged. The only difference inside the namespace is one file. Networking, D-Bus, /dev, the filesystem, and the LAN are all untouched, which is why nothing else breaks. systemd-resolved still performs all resolution (including DoH if you use it), glibc simply queries it at 127.0.0.53 over normal DNS instead of over D-Bus, and never sends the AAAA query.
Verify before launching Steam:
getent ahosts cache1-sea1.steamcontent.com
bwrap --dev-bind / / --bind /etc/steam-nsswitch.conf /etc/nsswitch.conf \
--setenv RES_OPTIONS no-aaaa getent ahosts cache1-sea1.steamcontent.com
The first prints both A and AAAA; the second should print IPv4 only.
Copy the desktop entry to your user directory so package updates don't overwrite it:
cp /usr/share/applications/steam.desktop ~/.local/share/applications/
Prefix every Exec= line, the main entry and all nine [Desktop Action] entries, with the bwrap invocation, keeping each line's existing arguments:
Exec=bwrap --dev-bind / / --bind /etc/steam-nsswitch.conf /etc/nsswitch.conf --setenv RES_OPTIONS no-aaaa /usr/bin/steam %U
Exec=bwrap --dev-bind / / --bind /etc/steam-nsswitch.conf /etc/nsswitch.conf --setenv RES_OPTIONS no-aaaa /usr/bin/steam steam://store
…and so on. Missing the action entries matters: launching one with no client running starts an unsandboxed Steam that quietly reverts to IPv6.
update-desktop-database ~/.local/share/applications
This also re-registers the x-scheme-handler/steam MIME association, so browser-launched steam:// links go through the sandbox too.
With a download running:
ss -tnp | grep steam | grep 443
Content connections should appear as [::ffff:a.b.c.d] (IPv4-mapped) rather than [2602:801:...].
gai.conf does not work as reported above, and I can confirm it. Also, a comment above suggests precedence ::/0 100 on the grounds that ::ffff:0:0/96 only matches NAT64 addresses. That is very wrong: ::ffff:0:0/96 is the IPv4-mapped range, which is exactly how getaddrinfo represents IPv4 results internally, and it is the form documented in gai.conf itself and in RFC 3484 §10.3. The original report had it right; the client just ignores the policy table.
The previously posted network namespace workaround has three problems worth documenting:
macvlan does not work over Wi-Fi. Most APs will not accept a second MAC address behind a single association, so DHCP in the namespace never completes. ipvlan mode l2 attaches fine on Wi-Fi because it shares the parent interface's MAC, but for the same reason it cannot do DHCP (it demultiplexes by IP address, and DHCP happens before an IP exists), so it requires a static address.ip netns exec … sudo -u $user steam appears to work. Steam starts normally, but the bootstrap hands off to systemd user activation, and the real client is spawned by your user manager, which lives in the host namespace. You end up with a Steam that looks sandboxed but is still using IPv6. Confirmed with readlink /proc/<pid>/ns/net and a failed app-steam@….service unit. Dropping DBUS_SESSION_BUS_ADDRESS from the environment avoids it, at the cost of desktop integration./etc/netns/<ns>/resolv.conf. Without it, the CEF store view fails with Error Code: -105 (ERR_NAME_NOT_RESOLVED) while downloads keep working, resulting in a confusing split failure, caused by the host resolv.conf pointing at 127.0.0.53, which is unreachable inside the namespace.Pinning /etc/hosts entries works but is not maintainable. You can enumerate the cache servers your client actually used:
grep -ohE '[a-z0-9-]+\.steamcontent\.com' ~/.local/share/Steam/logs/content_log.txt | sort -u
…and pin each to its A record. It works, but Valve adds and retires cache nodes, the list is region-specific, and a stale entry means the client hits a dead server. Useful as a diagnostic, and it is what validated finding number 2 above (but just like blackholing Valve's ipv6 address space, that approach is not useful as a real workaround)
The underlying bug is still that the client disregards the system's address-family preference and its own @nClientEnableIPv6ForHTTPPlatformLinux setting. Everything above is working around that from outside the client, because there is currently no way to do it from within Steam, and this very much needs some fixing in the client itself. Until then, this workaround should work fine for anyone affected by it.
Nothing extracted yet.
Your system information
Mar 23 2021, at 20:11:07Please describe your issue in as much detail as possible:
It seems that the steam client is not respecting the IPv6/IPv4 priority from
gai.confI have
precedence ::ffff:0:0/96 100ingai.confbut it seems that the client is still preferring IPv6 connections.For example, right now that I am downloading a game (from
netstat):Steps for reproducing this issue:
precedence ::ffff:0:0/96 100ingai.conf