protonscr

The client is not respecting the IPv6/IPv4 priority from gai.conf

steamopen Steam client
ValveSoftware/steam-for-linux#7716 · opened 2021-03-24 by naoliv · updated 2026-07-19 · 7 comments · github
Nnaoliv 2021-03-24 github

Your system information

  • Steam client version (build number or date): Mar 23 2021, at 20:11:07
  • Distribution (e.g. Ubuntu): Debian unstable
  • Opted into Steam client beta?: No
  • Have you checked for system updates?: Yes

Please describe your issue in as much detail as possible:

It seems that the steam client is not respecting the IPv6/IPv4 priority from gai.conf

I have precedence ::ffff:0:0/96 100 in gai.conf but it seems that the client is still preferring IPv6 connections.
For example, right now that I am downloading a game (from netstat):

tcp6       0      0 2804:c30:c21c:dd0:54537 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:39871 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0    292 2804:c30:c21c:dd0:36333 2602:801:f005:100:::443 ESTABLISHED 529939/steam        
tcp6       0    292 2804:c30:c21c:dd0:41539 2602:801:f005:100:::443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:50991 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0    292 2804:c30:c21c:dd0:38121 2602:801:f005:100:::443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:47815 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:36023 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:57385 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:54169 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:42121 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:41529 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0    292 2804:c30:c21c:dd0:48531 2602:801:f005:100:::443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:40959 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:42887 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:33387 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:38343 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:41091 2602:801:f005:100:::443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:46143 2602:801:f005:100:::443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:47353 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0    286 2804:c30:c21c:dd0:59439 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0      0 2804:c30:c21c:dd0:34959 2001:4de0:ac19::1:b:443 ESTABLISHED 529939/steam        
tcp6       0    292 2804:c30:c21c:dd0:34783 2602:801:f005:100:::443 ESTABLISHED 529939/steam        
tcp6       0    292 2804:c30:c21c:dd0:35041 2602:801:f005:100:::443 ESTABLISHED 529939/steam   

Steps for reproducing this issue:

  1. Set precedence ::ffff:0:0/96 100 in gai.conf
  2. Download something
  3. See that steam is only using IPv6
Bbooth-f 2021-11-01 github

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.

Nnaoliv 2021-11-01 github

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
Kkrzee 2023-01-04 github

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.

Ddakrk 2023-07-19 github

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.

Mmadezent 2023-09-22 github

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.

  • First, we add a new network namespace
    sudo ip netns add ipv4_only
  • We create a bridged virtual interface
    sudo ip link add macvlan0 link $network_interface type macvlan mode bridge
  • We add it to the created namespace
    sudo ip link set macvlan0 netns ipv4_only
  • We start the loop interface in the namespace
    sudo ip netns exec ipv4_only ip link set lo up
  • We get a new IPv4 address via DHCP in the namespace
    sudo ip netns exec ipv4_only dhclient
  • We disable IPv6 in the namespace
    sudo ip netns exec ipv4_only sysctl set net.ipv6.conf.macvlan0.disable_ipv6=1
  • We start steam in the namespace
    sudo ip netns exec ipv4_only sudo -u $user /usr/games/steam

Maybe I'll find time to automate this with systemd or some custom launcher for steam. Any ideas how to achieve that are appreciated.

Ccatgirlcataclysm 2024-05-12 github

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.

CChaoticHolon 2026-07-19 github

Forcing the Steam client to IPv4 per-process, without changing anything system-wide

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.


Findings

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.


The Workaround

If your system does not use systemd-resolved

If grep '^hosts:' /etc/nsswitch.conf shows files dns (no resolve), you need nothing else:

env RES_OPTIONS=no-aaaa steam

If your system uses systemd-resolved

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.

Making it permanent

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.

Verifying

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:...].


Notes on the existing workarounds in this thread

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.
  • Launching Steam inside the namespace silently fails on any D-Bus-activated desktop. 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.
  • The namespace needs its own /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.