Concept Web

How the components in this problem relate to one another. Hover or tap any node.

core mechanism
library / binary
environment
failure symptom
fix / mitigation
Diagnostic Decision Tree

Not sure what applies to your system? Walk through this to narrow it down before reading further.

Are you seeing Xlib: sequence lost messages in your terminal when launching Steam?
Open a terminal and run steam 2>&1 | head -50 to see the first 50 lines of output before deciding.
start → sequence lost confirmed
Did the errors start after a recent system update?
On rolling-release distros, libx11 or lib32-libx11 are the usual culprits. Check with pacman -Qe libx11 lib32-libx11 (Arch) or review your package manager's log.
start → sequence lost → post-update onset
Which distribution are you running?
start → sequence lost → unclear onset
Let's verify the version delta directly. Do you have the run-in-soldier or run-in-sniper scripts available?
Check with: ls ~/.local/share/Steam/steamapps/common/ | grep -i steamlinux
start → sequence lost → auditing container
Run the container audit command. Does the container libX11 version differ from your host version?
Run: ~/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper/run-in-sniper -- dpkg -l libx11-6 and compare the version shown against your host pacman -Q lib32-libx11.
start → different failure pattern
Different Problem Class

If games crash or refuse to launch without the sequence-lost flood, the problem is likely not a libX11 version mismatch. Check these common alternative causes:

  • Games installed on an NTFS volume — pressure-vessel cannot create symlinks on NTFS. Move games to ext4, Btrfs, or XFS.
  • linux-steam-integration package installed — try removing it.
  • systemd-resolved DNS symlink missing at /etc/resolv.conf.
  • Steam overlay disabled for the game — check per-game Properties → General.

Jump to the When It Isn't libX11 section for the full list.

start → proactive understanding
No Active Issue — Good Position To Be In

Understanding this problem before it hits means you will recognize it immediately when a rolling-release update eventually closes the gap in an unexpected direction.

The key things to internalize: pressure-vessel pins libraries to a Debian snapshot, your rolling-release host updates them independently, and capsule-capture-libs promotes the host version when it looks newer. That promotion is usually correct — until a point release introduces an ABI-level behavioral change the overlay was not compiled for.

start → sequence lost → Arch / Arch-based
Confirmed Path: Downgrade lib32-libx11

Downgrade lib32-libx11 to the most recent known-good version from the Arch archive, then add it to IgnorePkg in /etc/pacman.conf. The archive is at archive.archlinux.org.

If you would rather avoid ongoing maintenance, installing Flatpak Steam is the more durable alternative — it carries its own libX11 and removes this surface area entirely.

Security note: Holding any library at an older version means you will miss patches for it. Review Arch Security Advisories periodically.

start → sequence lost → Tumbleweed
Tumbleweed Path: Snapshot Rollback or Package Lock

Tumbleweed's Btrfs snapshot support lets you roll back the entire system to before the offending update using snapper. Once back on a working state, lock the package: sudo zypper al libX11-6.

Check locked packages anytime with sudo zypper ll. Unlock and retest after major libX11 version bumps.

start → sequence lost → Void Linux
Void Path: Switch to Flatpak Steam

Void does not maintain a package archive for downgrades, and building a specific version via xbps-src adds significant maintenance burden. The practical fix is Flatpak Steam, which brings its own isolated libX11.

start → sequence lost → general fix
Universal Path: Flatpak Steam

Flatpak Steam carries its own libX11 inside the Freedesktop Platform runtime, completely isolated from the host. This is the most distro-agnostic fix and eliminates this entire problem class at the cost of some flexibility with custom Proton builds and host-installed tools like MangoHud.

Rolling-release distributions like Arch Linux, Manjaro, Void Linux, and openSUSE Tumbleweed ship library updates as fast as upstream projects release them. For most desktop software, this is fine. For Steam on Linux, it creates a recurring class of problem that trips up even experienced users: the host operating system's version of libX11 advances past the version that Steam's container runtime was built against, and the container's internal hooks start behaving in ways their authors never tested.

The specific failure mode covered here is a version mismatch between the host libX11 and the pinned libX11 inside the Steam Linux Runtime's pressure-vessel container — and what that mismatch does to Steam's use of XCheckIfEvent(). The usual first response is to clear LD_PRELOAD, which works for a different class of library conflict but does not address this one. Getting to the right fix requires understanding what pressure-vessel actually is, why it pins libraries, and how to audit its library environment directly.

What pressure-vessel Actually Does

Steam ships two mechanisms for providing a consistent library environment to games. The older mechanism — the "scout" LD_LIBRARY_PATH runtime — injects libraries into a game process by prepending paths to the dynamic linker search order. It was the original solution to the "game compiled against Ubuntu 12.04 libraries, user is on Arch" problem, but it has a fundamental weakness: the host system's libraries and the runtime's libraries can interact in unexpected ways when both end up loaded.

The newer mechanism is pressure-vessel, which runs games inside a Linux namespace container — a lightweight sandbox that replaces /usr with the runtime's own library tree. This is what Steam Linux Runtime 2.0 ("soldier") and 3.0 ("sniper") use. As documented in the official steam-runtime-tools container documentation, soldier is based on Debian 10 (released 2019) and is designed exclusively as a container runtime for pressure-vessel — it cannot function as a LD_LIBRARY_PATH runtime. Sniper is based on Debian 11 (released 2021) and carries core libraries approximately two years newer than soldier.

As confirmed by the official ValveSoftware/steam-runtime repository, current versions of Proton (8.0 or newer) use the Steam Runtime 3 "sniper" container runtime, while older versions of Proton (5.13, 6.3, and 7.0) use the Steam Runtime 2 "soldier" container runtime. In November 2025, Valve also released Steam Linux Runtime 4 (steamrt4), based on Debian 13, skipping Debian 12 entirely — more on that below. Most users on modern systems are running inside sniper whenever they launch a Steam game through Proton 8.0 or later, or a native Linux game that has opted into the container runtime.

What This Means in Practice

When pressure-vessel is active, the game process runs inside a container where /usr is the runtime's library tree (Debian 11 for sniper, Debian 10 for soldier, Debian 13 for the newer SLR 4). However, certain libraries — especially graphics drivers and X11 libraries — are selectively pulled from the host to ensure hardware compatibility. This selective promotion is where version mismatches can enter the picture.

The tension here is between two goals that cannot both be fully satisfied: isolation (use only the container's vetted libraries) and hardware compatibility (use the host's GPU driver and X server libraries, which must match the running kernel and display server).

If pressure-vessel were fully isolated — using only its own Debian-pinned copies of every library — then Mesa updates, new GPU microarchitectures, and changes to the X server wire protocol would all break games silently. The container's Debian 11 Mesa would try to talk to a host GPU that expects a much newer ABI.

So Valve made a pragmatic choice: capsule-capture-libs promotes certain libraries from the host into the container when the host version is newer. For graphics drivers, this almost always works. For libX11, it works until a host point release carries a behavioral change the Steam overlay was not compiled against — and that is exactly the problem this article addresses.

Runtime Version Reference

Compare the library baselines across Steam Runtime generations to understand where version deltas are most likely to form.

runtime name
Steam Linux Runtime 3.0 "sniper" current default
base distro
Debian 11 (Bullseye, released 2021)
proton versions
Proton 8.0 and later; native Linux games like CS2, Dota 2
libX11 baseline
2:1.7.2 — Debian 11 series; generally aligned with 2021-era host versions
audit command
run-in-sniper -- dpkg -l libx11-6
mismatch risk
Moderate on Arch — host libX11 1.8.x series is two major revisions ahead of sniper's Debian 11 baseline
runtime name
Steam Linux Runtime 2.0 "soldier" legacy
base distro
Debian 10 (Buster, released 2019)
proton versions
Proton 5.13, 6.3, 7.0
libX11 baseline
2:1.6.7 — Debian 10 series; substantially older than current Arch host libraries
audit command
run-in-soldier -- dpkg -l libx11-6
mismatch risk
High on Arch — host libX11 is now approximately three major revisions ahead of the Debian 10 baseline
runtime name
Steam Linux Runtime 4 "steamrt4" Nov 2025
base distro
Debian 13 (Trixie) — skipped Debian 12 entirely
toolchain
glibc 2.40, gcc 14, SDL 3 with SDL 2 compatibility layer
libX11 baseline
Debian 13 series — significantly closer to current rolling-release host versions
mismatch risk
Lower at launch — but as a rolling-release host continues to advance, the same gap will eventually form
caveat
Drops i386 support for many packages — 32-bit native Linux games may need to remain on soldier or sniper

pressure-vessel uses a utility called capsule-capture-libs to decide which libraries to pull from the host versus which to use from the container's own copy. The selection logic, documented in the steam-runtime-tools container documentation, uses a capability-based comparison: if the host library is newer and ABI-compatible, it is promoted into the container in preference to the older version bundled with the runtime. This is intentional — it ensures, for example, that graphics driver userspace components (Mesa, NVIDIA) always come from the host.

For libX11, the decision is more nuanced. The Xlib library speaks directly to the X server, and its internal data structures — including the sequence number tracking used by functions like XCheckIfEvent() — have changed between versions in ways that are ABI-compatible at the symbol level but behaviorally different. A library bump that passes ABI-compatibility checks can still change how certain internal operations sequence events.

ABI compatibility is usually checked by whether the same function names exist and accept the same argument types. A dynamic linker will happily load a newer library if the symbols it exports match what the old one exported — the linker has no way to check whether the function behavior is the same.

Think of it like a door handle. The shape of the handle (the ABI) is the same, so anything that grabs handles still works. But the mechanism behind the door has changed — it now opens inward instead of outward. Everything looks compatible from the outside, but anyone who expects outward-opening behavior will fail at runtime.

For libX11, this showed up most clearly in the 1.8.x series: the sequence counter used internally for request tracking changed its overflow handling semantics. The symbol XCheckIfEvent still existed and still accepted the same arguments — but the Display* structure internals that gameoverlayrenderer.so was reading directly (not through the public API) changed underneath it.

Over time, ABI incompatibility issues arise when mixing the Steam runtime libraries with system libraries. The common scenario is when a system library is dynamically linked against a Steam runtime library and the Steam runtime provides a version with a different ABI. With libX11, this manifests in a specific way: Steam's overlay injector — gameoverlayrenderer.so — hooks into XCheckIfEvent() and depends on the event-sequence semantics that were present in the libX11 version it was compiled against.

XCheckIfEvent and the Steam Overlay Hook

XCheckIfEvent() is a non-blocking Xlib function that checks the event queue for an event matching a caller-supplied predicate, removes it if found, and returns without waiting otherwise. Steam's overlay renderer uses it as part of its input event interception pipeline — specifically to pull keyboard events intended for the overlay (like the Steam overlay shortcut) out of the event stream before they reach the game.

The hook itself works by intercepting the XCheckIfEvent symbol via LD_PRELOAD injection of gameoverlayrenderer.so. The overlay's replacement function calls the real XCheckIfEvent, inspects the result, and handles any events it wants to capture. This hook assumes that the Display* structure internals and the sequence counter layout inside libX11 match what the overlay was compiled against.

counterfactual
What if Steam hooked XCheckIfEvent through the public API instead of accessing Display* internals directly?
If the overlay only used the documented public Xlib API — never touching Display* struct fields directly — it would be insulated from internal layout changes. A future libX11 could rearrange the sequence counter storage entirely, and as long as the function signatures remained stable, the overlay would keep working. The reason this has not happened in practice is likely a combination of performance requirements (direct struct access avoids function call overhead in a hot event-processing path) and the sheer cost of refactoring a piece of infrastructure that has worked on most users' systems for years.

When the host libX11 is newer than the container-pinned version, and its internal representation of the sequence counter or reply queue has changed, the overlay's assumptions break. The result is the characteristic error message flooded to the terminal:

terminal output — sequence lost flood
Xlib: sequence lost (0x10000 > 0x2ad) in reply type 0x1c!
Xlib: sequence lost (0x10000 > 0x2ad) in reply type 0x1c!
Xlib: sequence lost (0x10000 > 0x2ad) in reply type 0x1c!
Xlib: sequence lost (0x10000 > 0x7!)
Xlib: sequence lost (0x10000 > 0x8!)

This flood is not cosmetic. At first, only a few of these messages appear, but over time the frequency increases. Launching any game, as well as opening the in-game overlay or any chat windows, causes more to appear, and after a while games start to crash or fail to launch. The sequence counter wrapping at 0x10000 indicates that Xlib's internal sequence tracking has lost synchronization with the X server's reply sequence — a state from which the connection generally cannot recover cleanly.

According to a Valve developer comment on ValveSoftware/steam-for-linux issue #11729 (February 2025), when the mismatch is active, the overlay renderer loads successfully but does nothing on a per-frame basis — only the XCheckIfEvent() hooks remain operational, and those are precisely what flood the sequence-lost buffer.

The Debian bug tracker documented the same class of failure in late 2022 when libx11-6 1.8.3 introduced changes that broke Xlib sequence tracking across multiple applications. After upgrading to libx11-6 2:1.8.3-2, applications began producing Xlib sequence lost errors, and in serious cases this caused processes to exit with a nonzero exit status.

Why LD_PRELOAD="" Is the Wrong Fix Here

The reflexive advice for Steam library problems on Arch Linux is to add LD_PRELOAD="" to the game's launch options. This clears any library preloads that Steam sets before launching the game process. It is a legitimate fix for a specific class of problem: when a preloaded library from Steam's environment clashes with a system library in a way that causes crashes or symbol lookup failures. The full picture of when and why LD_PRELOAD works for Steam — and when it silently does nothing — is worth understanding before reaching for it.

But the libX11 version mismatch is a different problem. The issue is not that a wrong library is being force-loaded via LD_PRELOAD. The issue is that pressure-vessel's library selection has promoted a newer host libX11 into the container — or alternatively, that the Steam client process outside the container is using a host libX11 that is newer than the overlay shared object was compiled against. Clearing LD_PRELOAD does not change which version of libX11 the dynamic linker resolves at runtime for the game or the overlay.

There are two separate injection points at play. Steam sets LD_PRELOAD to inject gameoverlayrenderer.so into game processes. Setting LD_PRELOAD="" in a game's launch options does clear this — which is why the overlay disappears entirely rather than stops crashing when you use that flag. You've removed the hook, not fixed it.

The version mismatch, however, lives at the library resolution layer beneath that. Whether or not gameoverlayrenderer.so is loaded, the dynamic linker will still choose the same libX11.so.6 — the one promoted from the host by capsule-capture-libs. The preload list is separate from the library search path.

So LD_PRELOAD="" effectively solves the symptom (no overlay hooks, no sequence-lost flood) by eliminating the overlay entirely, not by correcting the version mismatch. If you actually want the overlay to function, this is not a solution.

Misleading Symptom

The error ERROR: ld.so: object '.../gameoverlayrenderer.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored is a red herring and is present on essentially all 64-bit Arch Linux Steam installs. It means the 32-bit overlay renderer was ignored by the 64-bit dynamic linker — this is expected behavior and not related to the sequence-lost errors.

Auditing the Container's Library Environment

There are two sources of truth: the host system's libX11, and the version inside the pressure-vessel container.

Step 1: Check the host libX11

On Arch Linux, query both the 64-bit and 32-bit packages:

terminal — Arch Linux
$ pacman -Q libx11 lib32-libx11
libx11 1.8.10-1
lib32-libx11 1.8.10-1

On Void Linux or other xbps-based systems:

terminal — Void Linux
$ xbps-query -S libX11

Step 2: Read the runtime build stamp

Version numbers for some important runtime components are in VERSIONS.txt, and the log file is in the var/ directory named slr-app*-*.log for Steam games. Check both soldier and sniper if you have both installed:

terminal — VERSIONS.txt
$ cat ~/.local/share/Steam/steamapps/common/SteamLinuxRuntime_soldier/VERSIONS.txt
#Name           Version         Runtime         Runtime_Version Comment
depot           0.20241118.108551       # Overall version number
pressure-vessel 0.20241118.0    scout
scripts         0.20241118.0
soldier         0.20241118.108551       soldier 0.20241118.108551

The build date stamp in the depot version tells you which Debian 10 (soldier) or Debian 11 (sniper) snapshot the container's libraries were sourced from.

Step 3: Query the container's libX11 directly

This is the step that resolves all ambiguity. The run-in-soldier script (or run-in-sniper for the sniper runtime) launches a command inside the container's namespace. You can use it to query the container's package database:

terminal — query container libX11
$ ~/.local/share/Steam/steamapps/common/SteamLinuxRuntime_soldier/run-in-soldier -- dpkg -l libx11-6
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-========================================
ii  libx11-6:amd64 2:1.8.4-2+b1 amd64        X11 client-side library

You can also use ldd inside the container to verify which libX11 a specific binary will actually resolve against at runtime:

terminal — ldd inside container
$ ~/.local/share/Steam/steamapps/common/SteamLinuxRuntime_soldier/run-in-soldier -- ldd /usr/lib/x86_64-linux-gnu/libGL.so.1 | grep X11
	libX11.so.6 => /run/host/usr/lib/x86_64-linux-gnu/libX11.so.6 (0x...)

If the resolved path shows /run/host/usr/lib/..., pressure-vessel has promoted the host's libX11 into the container. If it shows a path without /run/host/, the container's own copy is being used. Either path can produce a mismatch if the promoted or bundled version diverges significantly from what Steam's overlay was compiled against.

Using steam-run for NixOS and Non-FHS Distros

On NixOS, where the filesystem hierarchy does not follow FHS conventions, the standard run-in-soldier script may not work correctly. The steam-run wrapper from nixpkgs creates a compatible FHS environment around Steam and its libraries. Running steam-run ldd /lib/libGL.so.1 from a NixOS system will show the resolved library paths within that wrapper's view of the filesystem, which is the environment Steam itself will use.

The Arch Linux libx11 1.8.x Regression: A Case Study

In December 2022, the Arch Linux package libx11 1.8.3-1 — specifically the 32-bit counterpart lib32-libx11 — introduced a regression that broke Steam games by causing the sequence-lost flood. The problem was isolated to the 32-bit package at version 1.8.3-1, while the 64-bit package at the same version was unaffected.

The failure pattern was documented precisely on the Arch Linux forums. Users reported that lib32-libx11 1.8.3-1 caused Xlib: sequence lost (0x10000 > 0x2ad) in reply type 0x1c! to flood the console on every Steam game launch, while downgrading to lib32-libx11 1.8.2-2 immediately resolved the issue. A later stable release, libx11 1.8.3-6, corrected the regression — but the window between the broken and fixed package caught a significant number of Arch users, and the same pattern has repeated with other libx11 point releases since.

An Arch Linux Forums participant in thread #282143 confirmed the asymmetry: both 32-bit and 64-bit packages may be installed at the same version number, but only the 32-bit build at 1.8.3-1 triggers the failure. The later release 1.8.3-6 corrected the regression. (Arch Linux Forums, thread #282143)

This incident illustrates why the problem class recurs: rolling-release distributions pick up libX11 point releases as they are tagged upstream, without the stabilization period that a fixed-release distribution like Debian provides. The Steam Runtime container is pinned to a specific Debian snapshot, and the combination of a promoted host library with an ABI regression can break the overlay's function hooks in ways that are not immediately obvious from the error output.

Fixes by Distribution

Arch Linux and Arch-Based Distributions (Manjaro, EndeavourOS, Garuda)

The first step is to confirm whether the current lib32-libx11 package version is the source of the problem. If a recent update to lib32-libx11 correlates with when the errors started, downgrade it using the Arch Linux package archive:

terminal — downgrade lib32-libx11 on Arch
# Downgrade to a known-good version from the Arch archive
$ sudo pacman -U "https://archive.archlinux.org/packages/l/lib32-libx11/lib32-libx11-1.8.9-1-x86_64.pkg.tar.zst"

# To hold the package at this version and prevent automatic upgrades:
# Add lib32-libx11 to the IgnorePkg line in /etc/pacman.conf
$ grep IgnorePkg /etc/pacman.conf
# IgnorePkg = lib32-libx11

Replace the version number with the most recent known-good version from the archive at archive.archlinux.org/packages/l/lib32-libx11/. You want the most recent package version that predates the update that caused your issues.

Holding a Package Has Security Implications

Freezing lib32-libx11 at an older version means you will not receive security patches for that package. Review the Arch Linux Security Advisories for libx11 periodically, and test newer versions as they are released to see if the regression has been resolved upstream.

If you would rather avoid the package-pinning maintenance burden entirely, Flatpak Steam is a practical alternative on Arch as well:

terminal — Flatpak Steam on Arch Linux
$ sudo pacman -S flatpak
$ flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
$ flatpak install flathub com.valvesoftware.Steam
Manjaro and Arch-Based Distributions with Staged Updates

Manjaro stages Arch packages through its own unstable, testing, and stable branches before promoting them, which typically introduces a lag of one to three weeks relative to the Arch upstream repositories. This means Manjaro users often encounter the libX11 mismatch problem at a different point in time than bare Arch users — sometimes avoiding a broken version entirely if Arch's regression is caught and patched within that window. The fix procedure is identical: query the installed lib32-libx11 version, compare against the container's baseline using run-in-soldier or run-in-sniper, and downgrade or switch to Flatpak if a delta exists. On Manjaro you can also roll back the entire system to a previous snapshot using Timeshift if Btrfs or RSYNC snapshots are enabled.

Void Linux

Void Linux does not provide an official package archive, but xbps-src can build specific versions from source if you need to pin a library version. The more practical approach is to switch to the Flatpak version of Steam, which bundles its own libX11 and is completely isolated from the host library versions:

terminal — Flatpak Steam on Void
$ sudo xbps-install flatpak
$ flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
$ flatpak install flathub com.valvesoftware.Steam

openSUSE Tumbleweed

Tumbleweed provides snapshot rollback via Btrfs snapshots. If a recent Tumbleweed update introduced a libX11 regression, you can roll back the entire system snapshot to before the update, identify the offending package, and pin it using the package lock mechanism:

terminal — pin a package on Tumbleweed
# Lock a specific package version to prevent updates
$ sudo zypper al libX11-6

# List current locks
$ sudo zypper ll

Consider Switching Runtime Versions

If you are using Proton 7.0 or older, your games default to the soldier container (Debian 10 baseline). Steam Runtime 3 "sniper" uses a Debian 11 baseline with a newer libX11 package — potentially one that is closer to your rolling-release host's current version, reducing the delta that causes mismatches. As documented in the official container runtime documentation, sniper is structurally identical to soldier but with a base distribution approximately two years newer, meaning its core libraries and compiler toolchain are also approximately two years newer.

As of November 2025, Valve released Steam Linux Runtime 4 (steamrt4), which skipped Debian 12 entirely and is based on Debian 13. This brings significantly newer core libraries including glibc 2.40, gcc 14, and an SDL 2 compatibility layer built atop SDL 3. If you are encountering libX11 mismatches with sniper, and the game you are running supports SLR 4, switching to it narrows the gap between the container's baseline and what modern rolling-release hosts carry. However, SLR 4 drops i386 support for many packages, so 32-bit native Linux games may need to remain on older runtimes.

To switch a specific game from soldier to sniper, right-click the game in your Steam library, select Properties, then Compatibility, check "Force the use of a specific Steam Play compatibility tool", and select Steam Linux Runtime 3.0 (sniper) or a Proton version that targets it (Proton 8.0 or later). You can also force sniper for native Linux games via the same menu.

Runtime Version vs Proton Version

The Steam Runtime version (soldier/sniper/SLR 4) and the Proton version are separate choices. Proton 8.0 and later use sniper by default. If you have a game pinned to Proton 7.0 for compatibility reasons, it will still use soldier even if sniper is installed. You can verify which runtime a game is currently using by enabling STEAM_LINUX_RUNTIME_LOG=1 as a launch option and examining the resulting log in ~/.local/share/Steam/steamapps/common/SteamLinuxRuntime_soldier/var/. The log file is named slr-app*-*.log for games with a Steam app ID.

Advanced and Alternative Approaches

The standard fixes — downgrading, locking the package, switching runtimes, or switching to Flatpak — cover the overwhelming majority of cases. If none of those options work for your situation, or if you need a more surgical approach that avoids the tradeoffs of each, the following techniques go further.

Prevent Host libX11 Promotion Without Downgrading

The core mechanism that causes the problem is capsule-capture-libs promoting the host's libX11 into the container when it detects a newer version. You can prevent this promotion for a specific game by adding an environment variable to its launch options that forces pressure-vessel to use only the container's own libraries for a specified path. The relevant environment variable is PRESSURE_VESSEL_COPY_RUNTIME_INTO_GAME=1, which instructs pressure-vessel to create a copy of the runtime rather than using bind mounts — this can change which libraries get promoted. A more targeted approach is to set STEAM_COMPAT_LIBRARY_PATHS to point at a directory containing a known-good libX11.so.6 build, placing that path ahead of any host or container resolution.

This is more fragile than the package-level solutions and requires you to maintain the known-good library build yourself, but it leaves the host package fully up to date while still protecting the specific game from the mismatch.

Use a Pacman Hook Instead of IgnorePkg

Rather than using IgnorePkg to freeze lib32-libx11 indefinitely, you can write a pacman hook that runs after any lib32-libx11 upgrade and automatically downgrades it back to your known-good version. This approach means you still receive the newer package into your local cache — and you can review the changelog — without it ever being active on your system. The hook goes in /etc/pacman.d/hooks/:

/etc/pacman.d/hooks/lib32-libx11-hold.hook
[Trigger]
Operation = Upgrade
Type = Package
Target = lib32-libx11

[Action]
Description = Re-pinning lib32-libx11 to known-good version after upgrade...
When = PostTransaction
Exec = /usr/bin/pacman -U --noconfirm "https://archive.archlinux.org/packages/l/lib32-libx11/lib32-libx11-1.8.9-1-x86_64.pkg.tar.zst"

The advantage over IgnorePkg is that you get a visible log entry on every affected upgrade, and the hook can be reviewed or disabled per-transaction more easily than editing pacman.conf. The disadvantage is the same: you are still running an older version of the library and accumulating any security debt that carries.

Build libX11 from a Specific Upstream Commit on Void

Void Linux's xbps-src build system lets you check out the void-packages repository, revert the libX11 template to a specific version, and build that version locally. The resulting package can be installed with xbps-install --repository=/path/to/hostdir/binpkgs and held in place by adding it to your /etc/xbps.d/ configuration with an ignorepkg directive. This gives you the same pinning result as the Arch archive approach but without an official archive to pull from, at the cost of a local build step each time the hold needs to be reset.

NixOS: Use steam-run with a Patched Shell Environment

On NixOS, the steam-run wrapper from nixpkgs creates an FHS-compliant environment around Steam's execution context. You can extend this wrapper in your NixOS configuration to override which libX11 is placed in the FHS environment — specifically, you can pin xorg.libX11 to a specific nixpkgs revision by locking your flake input or using an overlay. This gives you reproducible, declarative control over the exact library version Steam sees, without any manual downgrade steps. Because NixOS manages all state declaratively, reverting is as simple as updating the pinned revision and rebuilding the configuration.

Why This Is Easier on NixOS Than Arch

On Arch, pinning a package to a specific version requires active maintenance: you pull from the archive manually, set IgnorePkg, and check security advisories manually. On NixOS, the same outcome is achieved by locking a flake input to a specific commit of nixpkgs — the version is recorded in flake.lock, is reproducible, and can be rolled back to any previous state with nixos-rebuild switch --rollback. The NixOS model makes this class of library management significantly less error-prone.

Force the Container to Use Its Own libX11 via CAPSULE Override

The capsule-capture-libs selection logic can be influenced by setting STEAM_COMPAT_LIBRARY_PATHS to an empty string or by using the PRESSURE_VESSEL_FILESYSTEMS_RW variable to inject a controlled directory that shadows the host path. A more direct approach, if you are comfortable editing Steam's runtime scripts, is to find the capsule-capture-libs invocation inside the pressure-vessel wrapper and modify the if-newer:even-if-older: specifier for libX11 to only-soname:, which instructs it to use the container's version regardless of which is newer. This change is wiped out whenever Steam updates the runtime, so it requires re-applying after runtime updates — making it a debugging tool more than a sustainable production fix.

Enabling Verbose Runtime Logging for Diagnosis

When the standard symptoms are ambiguous — for example, when games crash silently without the sequence-lost flood, or when the crash only occurs on specific titles — enabling pressure-vessel's verbose logging is the next diagnostic step.

Steam accepts environment variables in your shell session before launch, or via a wrapper in the game's launch options. The most useful variables for this class of problem are:

launch environment variables
# Enable Steam Linux Runtime verbose logging (set before launching Steam)
$ STEAM_LINUX_RUNTIME_VERBOSE=1 steam

# Enable pressure-vessel's own verbose output
$ PRESSURE_VESSEL_VERBOSE=1 steam

# Combined with Proton logging for a full picture
$ STEAM_LINUX_RUNTIME_VERBOSE=1 PROTON_LOG=1 steam

The runtime log files are written to the var/ subdirectory of whichever Steam Linux Runtime is active. The log file is named slr-app*-*.log for Steam games, or slr-non-steam-game-*.log if Steam cannot identify a Steam app ID for the game.

Within the pressure-vessel log, look for lines referencing capsule-capture-libs and the library selection for libX11. You will see output showing whether each library was taken from the host (/run/host/) or the container, and what version comparison logic was applied.

example pressure-vessel log excerpt
# Example of library selection in a pressure-vessel log
pressure-vessel-wrap[12345]: D: run: '.../capsule-capture-libs'
  '--provider' '/'
  '--library-knowledge' '.../libcapsule-knowledge.keyfile'
  'if-newer:even-if-older:path:/usr/lib/x86_64-linux-gnu/libX11.so.6'
# "if-newer" means: use host version if it's newer than the container's
# This is the line that confirms host libX11 promotion is active

Flatpak Steam as a Long-Term Solution

For rolling-release users who find themselves repeatedly chasing library compatibility issues, the Flatpak version of Steam is the most durable long-term solution. Flatpak Steam runs in its own runtime sandbox (the Freedesktop Platform runtime) and carries its own copies of Xlib, Mesa stubs, and other foundational libraries, independent of whatever the host system has installed.

This eliminates the version mismatch problem at the cost of some flexibility: Flatpak Steam cannot access user-installed MangoHud or GameMode installations without explicit Flatpak overrides, and certain custom Proton builds require manual placement in the correct Flatpak data directory. For the average user who just wants games to work after a system update, the tradeoff is generally worth it.

It is worth noting that Flatpak Steam still uses pressure-vessel internally for Proton games — the Flatpak runtime provides the outer container, and pressure-vessel provides the inner game environment. The key difference is that the Steam client itself and its overlay shared objects run against the Flatpak runtime's own libX11 rather than the host's, which removes the surface area for the mismatch described in this article.

It could, in theory — but there is an important difference in which libX11 the Steam client and overlay load. In native Steam, the Steam client executable resolves against the host system's libX11 directly. The overlay (gameoverlayrenderer.so) is therefore also operating against the host's libX11, outside any container boundary.

In Flatpak Steam, the Steam client process lives inside the Freedesktop Platform runtime. Its libX11 is the one bundled with that runtime — a version Flatpak controls and updates independently of your rolling-release host. When pressure-vessel then runs a game inside its own inner container, the host promotion logic still applies to the game process, but the overlay that hooks XCheckIfEvent is running against the Flatpak runtime's libX11, not the host's.

The net effect: the host/overlay version delta that causes the sequence-lost flood is eliminated at the Steam client layer. Whether the inner game process ever encounters its own libX11 conflict is a much smaller surface area and has not been a documented source of this specific failure.

Related Reading

If you are on or considering a gaming-focused distribution that pre-patches these issues, see the article on Nobara Linux — GloriousEggroll's patched Fedora build that ships with Steam compatibility fixes pre-applied. For the full picture on SteamOS-based approaches, see Linux Gaming with SteamOS and HoloISO. If you are evaluating Fedora as a more stable gaming base, see optimizing Fedora for gaming with Steam and GPU drivers.

Confirming the Fix Worked

After applying any of the fixes above, verify that the problem is actually resolved before considering the issue closed. The simplest test is to launch Steam from a terminal and watch the output:

terminal — verify fix
# Launch Steam from terminal and watch for sequence-lost messages
$ steam 2>&1 | grep -i "sequence lost"

# If the output is empty after launching a game, the fix is working.
# For verbose confirmation of which libX11 is now being selected:
$ STEAM_LINUX_RUNTIME_VERBOSE=1 steam 2>&1 | grep -i "libX11"

A successful fix produces no Xlib: sequence lost output when Steam and its games are running. If you used STEAM_LINUX_RUNTIME_VERBOSE=1, the pressure-vessel log in the runtime's var/ directory will show the library selection logic — look for the libX11 line and confirm that the path shown (host or container) corresponds to a version that does not produce the error.

After confirming resolution, launch one of the games that was previously affected and verify that it opens without the overlay failing or the game crashing. The sequence-lost flood typically reappears within the first few seconds of a game launch if the mismatch is still present, so a clean launch is strong confirmation.

Set a Reminder to Retest After System Updates

If you have pinned lib32-libx11 at an older version using IgnorePkg, that pin will survive indefinitely until you remove it. Each time a new libx11 version is released, it is worth testing — the regression may have been resolved in a later point release, and holding an old version indefinitely has ongoing security costs. A practical approach is to remove the IgnorePkg entry after a major libX11 version bump, update, and verify before re-adding it if the problem reappears.

Does Running Under Wayland Change Anything?

This question comes up often, and the answer matters: running your desktop session under a Wayland compositor — KDE Plasma Wayland, GNOME Wayland, Hyprland, Sway, or any other — does not protect you from this problem and does not change the diagnostic or fix process in any way.

The Steam client, as of early 2026, is still an X11 application. It does not have a native Wayland backend. When launched under a Wayland session, Steam runs through XWayland — the X server compatibility layer that allows X11 applications to operate inside a Wayland compositor. XWayland provides a standard Xlib environment to Steam, which means gameoverlayrenderer.so still hooks XCheckIfEvent() via the same mechanism, the same libX11 version comparison between host and container still applies, and the same sequence-lost flood still occurs when a mismatch exists.

Steam Client and X11 — As of Early 2026

As of early 2026, the Steam client has no native Wayland backend and runs exclusively through X11 or XWayland. This was confirmed in the Steam Client Beta discussion forums in late 2025, and the situation remains unchanged.

The XWayland layer translates X11 protocol calls into Wayland protocol calls for the compositor, but it does so transparently — from Steam's perspective and from pressure-vessel's perspective, the library environment is indistinguishable from a native X11 session. The libX11 that Steam resolves is the host system's libX11 whether the session is X11 or XWayland, because that is what XWayland provides.

This also means that if you encounter the sequence-lost errors under Wayland, switching your session back to X11 will not resolve the underlying library mismatch — it will simply swap one X server for another while the same version conflict persists. The fix remains the same regardless of the session type: audit the container, identify the version delta, and apply the appropriate distro-specific fix.

counterfactual
What changes when Steam finally ships a native Wayland backend?
A native Wayland Steam client would speak the Wayland protocol directly, bypassing XWayland and the Xlib stack entirely. The Steam client process would no longer link against libX11.so.6 for its own windowing and event handling. The XCheckIfEvent hook in gameoverlayrenderer.so would need to be replaced or augmented with Wayland-native event interception. The host/container libX11 version delta would become irrelevant for the Steam client itself — though games that still use X11 internally (or through XWayland) might still carry the same surface area at the game process level. Proton 10's experimental PROTON_ENABLE_WAYLAND=1 flag is the first concrete movement in this direction for game processes, but the client itself has not yet followed.
Proton 10 and Native Wayland Games

Proton 10.0 includes an experimental native Wayland backend for Wine that allows some Windows games to render directly to a Wayland surface rather than through XWayland. When a game uses this path, it does not go through the XCheckIfEvent hook in the same way, potentially sidestepping the specific overlay failure described in this article. However, this path is still experimental, not all games support it, and the Steam client itself still requires XWayland regardless. Enable it with the launch option PROTON_ENABLE_WAYLAND=1 %command% and verify per-game whether it resolves issues for you.

When It Is Not Actually a libX11 Problem

Not every instance of the Xlib sequence-lost message or overlay failure maps to a libX11 version mismatch. Before spending time on library audits, rule out these more common and simpler causes:

Summary: The Correct Diagnostic Path

The libX11 version mismatch problem on rolling-release distributions follows a consistent diagnostic path. First, confirm that the sequence-lost flood is present in terminal output when launching Steam from a terminal. Second, correlate the onset of the problem with a recent system update — specifically any update to libx11 or lib32-libx11. Third, use run-in-soldier or run-in-sniper to query the container's own libX11 version and compare it against the host's version.

If a version delta exists and correlates with the problem start date, the fix is to downgrade the host package to the version nearest to the container's baseline, switch the runtime from soldier to sniper if the sniper baseline is a closer match, or migrate to Flatpak Steam to exit the version mismatch game entirely. The LD_PRELOAD="" launch option addresses a different class of problem and will not resolve a version mismatch between container and host libraries.

The pressure-vessel container technology was built specifically to insulate games from host library chaos — but that insulation depends on the host/container boundary being well-managed. On rolling-release distributions, maintaining that boundary requires periodic attention that fixed-release distributions get automatically.

Sources