Skip to content

Instantly share code, notes, and snippets.

@srid
Last active September 6, 2026 20:43
Show Gist options
  • Select an option

  • Save srid/6971a6ef8411af26396249ad706ae0ed to your computer and use it in GitHub Desktop.

Select an option

Save srid/6971a6ef8411af26396249ad706ae0ed to your computer and use it in GitHub Desktop.
kolu-ci-3: zero-length .drv in the Nix store (filesystem corruption) — juspay/kolu#2234

kolu-ci-3: ~4,200 truncated files from one crash — recycle the container

Host: kolu-ci-3 (kolu CI venue pool, x86_64-linux, Incus container) Status: still live and taking CI work — pull it from the pool now Verdict: one unclean shutdown two weeks ago, not a failing disk. Recycle the container.

Correction: the first version of this gist said "one specific store path is damaged." That was wrong about scope, and acting on it would not have fixed anything — see below. The symptom and the host are right; the blast radius was understated by three orders of magnitude.

Symptom

ci::home-manager fails in ~1.2 s:

error: error parsing derivation '/nix/store/0mvnbryv5wvkryyw2m67xhnx5vj359gk-initrd-linux-6.18.39.drv': file is empty (possible filesystem corruption)

Actual scope

That file is 0 bytes — and it is one of 82 zero-length .drv files. A .drv can never legitimately be empty. Its same-kernel sibling (xkygb35z5yw7l4sp2kp0mx260jppd4zc-initrd-linux-6.18.39.drv) is also empty, as is the whole enclosing closure: nixos-system-machine-test.drv, activate.drv, etc.drv, initrd-units.drv, boot.json.drv.

Widened sweep: ~4,207 zero-length files across 168 registered store paths.

nix-store --verify --check-contents has now run to completion and confirms that number by a second, independent method:

Result Count
Paths reported modified 168
…truncated to empty (NAR hash of a zero-byte file) 162
…non-empty hash mismatch 6

The 6 non-empty mismatches are not separate corruption. Every one is a directory store path (release-notes, three source trees, pkgs-lib, lib) whose hash changed only because truncated files sit inside it — and every truncated file inside them carries the same ctime as the rest. One of them, kjgdxcjz…-source, accounts for 2,845 of the ~4,207 truncated files by itself.

100% of the damage Nix can detect traces to a single minute. No second fault, no ongoing rot.

The damaged set is the NixOS VM-test closure, so this breaks at least six lanes, not just home-manager: vm-test-run-kolu-{service,offline-provision,adoption-upgrade,adoption-upgrade-reboot}, kolu-upgrade-verify-reboot, kolu-agent-closure-containment, plus unit-home-manager-alice.service.drv.

Root cause: a single crash, 2026-08-22

Every truncated file shares one ctime minute, and last -x records that boot session ending in crash (Sat Aug 22 14:02 - crash):

Minute Files created Zero-length Rate
2026-08-22 16:38 10,168 4,207 41.4%
2026-09-05 14:07 100,202 899 0.9%
typical minute ~11,000 ~19 0.2%

Baseline 0.1–0.9% is legitimately-empty files inside packages. That one minute is 50–400× baseline. Metadata committed, data extents never did — textbook unclean shutdown.

Evidence it is NOT ongoing hardware failure

  • no I/O errors in dmesg; btrfs mounted rw, no read-only remount
  • /nix 15% used, 1.6 T free
  • structural nix-store --verify clean (it is contents that are lost, not links)
  • every .drv written since — Aug 24, Sep 3–6, thousands — is healthy
  • only 1 of 93 flagged paths is a non-empty hash mismatch, and it is a directory containing the same truncated files — same event, not separate bit-rot

Blast radius is contained

This is an Incus container on Nix's experimental local-overlay store. All 82 truncated .drvs are in the container's writable upper layer (/var/lib/nix/overlay/upper); the shared lower store has zero truncated .drvs. All six sibling pool boxes (kolu-ci-5,6,7,8,9,10) were checked and are clean. The base image is intact; the pool is not contaminated.

Recommended fix

  1. Pull kolu-ci-3 from the venue pool immediately. It is still live and still writing (store activity observed the same day), so it keeps handing red lanes to whoever draws it — and the failures read like repo problems.
  2. Recycle the container. It is a disposable pu box on a verifiably clean lower store, so re-creating it is cheaper and more certain than repairing.
  3. If you would rather repair in place: delete all ~168 damaged paths and let Nix re-realise them. nix-store --repair genuinely cannot help — these are locally-built .drvs and a .drv has no substituter to re-fetch from.
  4. No disk action needed. If you want belt-and-braces, a btrfs scrub will confirm there is nothing structurally wrong.

Note

Nothing on the host was changed — no repair, no delete, no config or service touched. sudo requires an interactive password there, and the scope finding above made the originally-proposed single-file deletion pointless anyway. The completed verify log is left at /tmp/verify.log for review; temporary scripts were removed.

Files here

  • ci-home-manager-tail.log — the failing lane's log, including the error
  • ci-home-manager-head.log — the start, showing it got no further than flake input resolution
  • error-lines.txt — the two error lines on their own

Seen on juspay/kolu PR #2234, commits 7fe603e25 and c02228625, lane ci::home-manager.

if [ "$(uname)" = Darwin ]; then bash ci/flake-build --kinds checks ./nix/home/example -- --override-input kolu .; else bash ci/flake-build --kinds checks --nixos-toplevels ./nix/home/example -- --override-input kolu .; fi
warning: not writing modified lock file of flake 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?dir=nix/home/example':
• Updated input 'kolu':
'github:juspay/kolu/cb42d2f422272e5a3188220b74a8004ed1887b4b?narHash=sha256-EujawtsKFOdPZ7RyFXj4s2%2BqhVqAn3cSgUlERfSLHZM%3D' (2026-03-21)
→ 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?rev=c022286253648d35caea024f8a7b9dd0800ee08b' (2026-09-06)
• Removed input 'kolu/flake-parts'
• Removed input 'kolu/flake-parts/nixpkgs-lib'
• Removed input 'kolu/git-hooks'
• Removed input 'kolu/nixpkgs'
• Removed input 'kolu/process-compose-flake'
• Removed input 'kolu/systems'
warning: not writing modified lock file of flake 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?dir=nix/home/example':
• Updated input 'kolu':
'github:juspay/kolu/cb42d2f422272e5a3188220b74a8004ed1887b4b?narHash=sha256-EujawtsKFOdPZ7RyFXj4s2%2BqhVqAn3cSgUlERfSLHZM%3D' (2026-03-21)
→ 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?rev=c022286253648d35caea024f8a7b9dd0800ee08b' (2026-09-06)
• Removed input 'kolu/flake-parts'
• Removed input 'kolu/flake-parts/nixpkgs-lib'
• Removed input 'kolu/git-hooks'
• Removed input 'kolu/nixpkgs'
• Removed input 'kolu/process-compose-flake'
• Removed input 'kolu/systems'
warning: not writing modified lock file of flake 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?dir=nix/home/example':
• Updated input 'kolu':
'github:juspay/kolu/cb42d2f422272e5a3188220b74a8004ed1887b4b?narHash=sha256-EujawtsKFOdPZ7RyFXj4s2%2BqhVqAn3cSgUlERfSLHZM%3D' (2026-03-21)
→ 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?rev=c022286253648d35caea024f8a7b9dd0800ee08b' (2026-09-06)
• Removed input 'kolu/flake-parts'
• Removed input 'kolu/flake-parts/nixpkgs-lib'
• Removed input 'kolu/git-hooks'
• Removed input 'kolu/nixpkgs'
• Removed input 'kolu/process-compose-flake'
u/kolu/c022286-1517638-a15515c3?dir=nix/home/example':
• Updated input 'kolu':
'github:juspay/kolu/cb42d2f422272e5a3188220b74a8004ed1887b4b?narHash=sha256-EujawtsKFOdPZ7RyFXj4s2%2BqhVqAn3cSgUlERfSLHZM%3D' (2026-03-21)
→ 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?rev=c022286253648d35caea024f8a7b9dd0800ee08b' (2026-09-06)
• Removed input 'kolu/flake-parts'
• Removed input 'kolu/flake-parts/nixpkgs-lib'
• Removed input 'kolu/git-hooks'
• Removed input 'kolu/nixpkgs'
• Removed input 'kolu/process-compose-flake'
• Removed input 'kolu/systems'
warning: not writing modified lock file of flake 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?dir=nix/home/example':
• Updated input 'kolu':
'github:juspay/kolu/cb42d2f422272e5a3188220b74a8004ed1887b4b?narHash=sha256-EujawtsKFOdPZ7RyFXj4s2%2BqhVqAn3cSgUlERfSLHZM%3D' (2026-03-21)
→ 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?rev=c022286253648d35caea024f8a7b9dd0800ee08b' (2026-09-06)
• Removed input 'kolu/flake-parts'
• Removed input 'kolu/flake-parts/nixpkgs-lib'
• Removed input 'kolu/git-hooks'
• Removed input 'kolu/nixpkgs'
• Removed input 'kolu/process-compose-flake'
• Removed input 'kolu/systems'
warning: not writing modified lock file of flake 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?dir=nix/home/example':
• Updated input 'kolu':
'github:juspay/kolu/cb42d2f422272e5a3188220b74a8004ed1887b4b?narHash=sha256-EujawtsKFOdPZ7RyFXj4s2%2BqhVqAn3cSgUlERfSLHZM%3D' (2026-03-21)
→ 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?rev=c022286253648d35caea024f8a7b9dd0800ee08b' (2026-09-06)
• Removed input 'kolu/flake-parts'
• Removed input 'kolu/flake-parts/nixpkgs-lib'
• Removed input 'kolu/git-hooks'
• Removed input 'kolu/nixpkgs'
• Removed input 'kolu/process-compose-flake'
• Removed input 'kolu/systems'
warning: not writing modified lock file of flake 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?dir=nix/home/example':
• Updated input 'kolu':
'github:juspay/kolu/cb42d2f422272e5a3188220b74a8004ed1887b4b?narHash=sha256-EujawtsKFOdPZ7RyFXj4s2%2BqhVqAn3cSgUlERfSLHZM%3D' (2026-03-21)
→ 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?rev=c022286253648d35caea024f8a7b9dd0800ee08b' (2026-09-06)
• Removed input 'kolu/flake-parts'
• Removed input 'kolu/flake-parts/nixpkgs-lib'
• Removed input 'kolu/git-hooks'
• Removed input 'kolu/nixpkgs'
• Removed input 'kolu/process-compose-flake'
• Removed input 'kolu/systems'
warning: not writing modified lock file of flake 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?dir=nix/home/example':
• Updated input 'kolu':
'github:juspay/kolu/cb42d2f422272e5a3188220b74a8004ed1887b4b?narHash=sha256-EujawtsKFOdPZ7RyFXj4s2%2BqhVqAn3cSgUlERfSLHZM%3D' (2026-03-21)
→ 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?rev=c022286253648d35caea024f8a7b9dd0800ee08b' (2026-09-06)
• Removed input 'kolu/flake-parts'
• Removed input 'kolu/flake-parts/nixpkgs-lib'
• Removed input 'kolu/git-hooks'
• Removed input 'kolu/nixpkgs'
• Removed input 'kolu/process-compose-flake'
• Removed input 'kolu/systems'
warning: not writing modified lock file of flake 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?dir=nix/home/example':
• Updated input 'kolu':
'github:juspay/kolu/cb42d2f422272e5a3188220b74a8004ed1887b4b?narHash=sha256-EujawtsKFOdPZ7RyFXj4s2%2BqhVqAn3cSgUlERfSLHZM%3D' (2026-03-21)
→ 'git+file:///tmp/odu/kolu/c022286-1517638-a15515c3?rev=c022286253648d35caea024f8a7b9dd0800ee08b' (2026-09-06)
• Removed input 'kolu/flake-parts'
• Removed input 'kolu/flake-parts/nixpkgs-lib'
• Removed input 'kolu/git-hooks'
• Removed input 'kolu/nixpkgs'
• Removed input 'kolu/process-compose-flake'
• Removed input 'kolu/systems'
error: error parsing derivation '/nix/store/0mvnbryv5wvkryyw2m67xhnx5vj359gk-initrd-linux-6.18.39.drv': file is empty (possible filesystem corruption)
error: recipe `home-manager` failed on line 176 with exit code 1
122:error: error parsing derivation '/nix/store/0mvnbryv5wvkryyw2m67xhnx5vj359gk-initrd-linux-6.18.39.drv': file is empty (possible filesystem corruption)
123:error: recipe `home-manager` failed on line 176 with exit code 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment