Fix for SteamOS system updates failing on custom hardware with SATA storage (non-Deck machines: generic x86 mini-PCs, console-style builds like the Atari VCS 800, custom living-room PCs, and similar).
If your SteamOS update fails at the bootloader step with a rolled-back install and journal messages like:
rauc-override.sh: mount: /run/steamos-chroot/this-B/etc: fsconfig system call failed: Stale file handle.
rauc-override.sh: Failed to mount the /etc overlay.
rauc-override.sh: Error: Failed to install bootloaders
rauc[...]: Installation ... failed: Post-install handler error: Child process exited with code 1
— this repo is for you.
Related upstream issue (closed without a fix): ValveSoftware/SteamOS#2055 — Automount of /run/media/deck/var breaks updates
SSH into the affected machine (or open a Konsole in Desktop Mode) and run:
curl -fsSL https://raw.githubusercontent.com/actimmo/steamos-sata-update-fix/main/fix-steamos-update.sh -o /tmp/fix-steamos-update.sh
chmod +x /tmp/fix-steamos-update.sh
sudo /tmp/fix-steamos-update.sh
sudo steamos-updateThat's it. After the update finishes, reboot.
Prefer to look before you leap?
/tmp/fix-steamos-update.sh --diagnose # read-only, no root needed to diagnose
sudo /tmp/fix-steamos-update.sh --dry-runThe script is idempotent and safe to re-run.
Typical story: SteamOS (usually on 3.7.x) has been working fine; an update shows up in the Steam UI; the update progresses through the download and "copying image" phases, then fails near 100% with a generic "update failed" message. Reboots don't help; retrying shows the same failure.
In journalctl -b 0 | grep rauc-override you see:
Installing the bootloaders
mount: /run/steamos-chroot/this-B/etc: fsconfig system call failed: Stale file handle.
Failed to mount the /etc overlay.
Error: Failed to install bootloaders
Installation ... failed: Post-install handler error: Child process exited with code 1
And rauc status shows slot B as boot status: bad.
Anyone running SteamOS where the internal disk is SATA (appears as
/dev/sda, /dev/sdb, etc.) rather than NVMe (/dev/nvme0n1) or eMMC
(/dev/mmcblk0). Concretely:
- Custom-built Steam machines with SATA SSDs.
- Mini-PCs (Beelink, ASRock, and similar) repurposed as a SteamOS living-room box.
- Atari VCS 800 and similar console-form-factor hardware.
- Handheld clones that expose their internal storage as SATA.
Stock Steam Decks (LCD and OLED) are not affected — their internal storage
is eMMC (mmcblk0) or NVMe (nvme0n1), which the buggy udev rule happens to
skip for unrelated reasons.
Walk the failure chain:
- SteamOS uses RAUC for atomic A/B updates. RAUC writes
the new rootfs image to the inactive slot (
rootfs.1), then runs/usr/lib/rauc/post-install.sh→rauc-override.shto regenerate the bootloader config for the new slot. rauc-override.shcallssteamos-chroot --partset other -- ....steamos-chrootneeds to mount the new slot's root and/var, then layer an overlayfs for/etcon top (because/etcon SteamOS is always an overlay whose upper dir lives on/var).- On the stock Deck, the inactive slot's
/varis unmounted at this point, sosteamos-chrootcan mount it wherever it likes. - On custom SATA hardware, the inactive slot's
/varhas already been auto-mounted at/run/media/deck/varby Valve's99-steamos-automount.rules, which fires on anysd*ormmcblk*block device with a filesystem. The rule doesn't distinguish the internal disk from a USB stick because on the Deck the internal disk isn'tsd*, so the need never arose. steamos-chrootmounts/vara second time under its own temp dir, then triesmount -t overlay lowerdir=.../etc,upperdir=.../var/lib/overlays/etc/upper,.... That overlay mount fails withfsconfig system call failed: Stale file handlebecause of how Linux's VFS handles the upper/work dirs living on a filesystem that is also live-mounted elsewhere with an incompatible state.- RAUC sees the post-install handler exited non-zero, marks the new slot as
boot status: bad, and rolls back. - The failed attempt leaves
upper/andwork/dirs behind in the inactive slot's/var/lib/overlays/etc/. Even after you unmount the auto-mount, those leftovers cause subsequent attempts to fail the same way — so a naive "just unmount and retry" doesn't always work.
Two things:
fix-steamos-update.sh— an idempotent script that detects whether the bug applies, stops the offending systemd.mountunits, cleans the stale overlay leftovers on the inactive slot's/var, and installs a persistent udev rule so the bug doesn't recur.udev/10-steamos-no-automount-internal.rules— the persistent fix on its own, in case you want to install it by hand. The rule matches by GPT partition label (ID_PART_ENTRY_NAME), so it's independent of which/dev/sd*slot the disk lands in, and it lives in/etc/udev/rules.d/so it survives SteamOS rootfs swaps.
If you'd rather do it yourself, here's the full sequence. Run as root.
# 1. Identify any systemd mount units auto-mounting internal A/B partitions.
systemctl list-units --type=mount --all | grep run-media-deck
# 2. Stop them. Common name is run-media-deck-var.mount for the var-B slot.
sudo systemctl stop run-media-deck-var.mount
# 3. Clean stale overlay leftovers on the inactive slot's /var.
# Replace "B" with "A" if you're booted from slot B.
sudo mkdir -p /mnt/var-other
sudo mount /dev/disk/by-partsets/B/var /mnt/var-other
sudo rm -rf /mnt/var-other/lib/overlays/etc/upper /mnt/var-other/lib/overlays/etc/work
sudo umount /mnt/var-other
sudo rmdir /mnt/var-other
# 4. Install the persistent udev rule.
sudo tee /etc/udev/rules.d/10-steamos-no-automount-internal.rules > /dev/null <<'EOF'
# See https://github.com/valvesoftware/steamos/issues/2055
# See https://github.com/actimmo/steamos-sata-update-fix
ENV{ID_PART_ENTRY_NAME}=="rootfs-A|rootfs-B|var-A|var-B|efi-A|efi-B", ENV{SYSTEMD_READY}="0", ENV{UDISKS_IGNORE}="1"
EOF
sudo udevadm control --reload
sudo udevadm trigger --subsystem-match=block
# 5. Retry the update.
sudo steamos-updateReboot when steamos-update finishes successfully.
After running either path, confirm:
# 1. No internal A/B partition should be mounted under /run/media/deck/.
mount | grep /run/media/deck
# 2. rauc status should show the other slot as 'good', not 'bad',
# and Activated = rootfs.1 (if you just updated from A).
sudo rauc status
# 3. The reboot-for-update flag should exist.
ls -la /run/steamos-atomupd/reboot_for_updateIf all three check out, reboot and you're on the new SteamOS version.
You can, and the Valve-issue thread suggests it:
sudo sed -i 's|KERNEL!="mmcblk\*|sd\*"|KERNEL!="mmcblk*"|' \
/usr/lib/udev/rules.d/99-steamos-automount.rulesBut /usr/lib/udev/rules.d/ lives on the rootfs, which is swapped on every
SteamOS update. Your patch gets undone as soon as the next update succeeds. The
rule in this repo lives in /etc/udev/rules.d/, which is an overlay backed by
/var and is carried across rootfs swaps.
- SteamOS 3.7.20 → 3.7.21 (build 20260108.1 → 20260414.1), stable branch, on custom SATA hardware (x86_64, AMD APU, 465 GB SATA SSD, kernel 6.11.11-valve27).
- Partition layout: standard SteamOS GPT labels
(
esp,efi-A/efi-B,rootfs-A/rootfs-B,var-A/var-B,home).
Issues and PRs welcome. If you hit a variant of this bug on different hardware or a different SteamOS version, please file an issue with:
- Output of
fix-steamos-update.sh --diagnose journalctl -b 0 | grep -iE "rauc|atomupd|steamos-chroot"around the failurelsblk -o NAME,PARTLABEL,LABEL,SIZE,MOUNTPOINT
MIT. See LICENSE.
- Original bug report: ValveSoftware/SteamOS#2055 by @macromorgan (Atari VCS 800).
- Full post-install / overlayfs analysis, stale-leftover angle, durable udev fix, and this repo: @actimmo.