You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A single transient non-200 from cache.nixos.org makes devbox run fail hard, even
when every store path is already present in the local nix store.
On a GitHub Actions runner, with the whole /nix/store restored from cache moments
earlier:
Info: Ensuring packages are installed.
Error: error running script "echo" in Devbox: execute template flake.nix.tmpl:
template: flake.nix.tmpl:52:33: executing "flake.nix.tmpl" at
<$pkg.InputAddressedPathForOutput>: error calling InputAddressedPathForOutput:
Package "gdk-pixbuf@latest" cannot be fetched from binary cache store
All six gdk-pixbuf x86_64-linux store paths in our devbox.lock return 200 from cache.nixos.org, before and after the failure. Re-running the identical job, same
commit, same lockfile, succeeded with no changes. Out of 45 jobs in that CI run using
the same lockfile at the same moment, exactly one failed.
Root cause
fetchNarInfoStatusFromHTTP treats any non-200 as "this path is not in the cache"
(internal/devpkg/narinfo_cache.go:228):
returnres.StatusCode==http.StatusOK, nil
A 429, 503 or 403 from the CDN is therefore recorded identically to a genuine 404. There is no retry, and the request carries a 5s deadline
(narinfo_cache.go:216).
That result then propagates as fact:
areExpectedOutputsInCacheOnce (narinfo_cache.go:89) requires every default
output to be present: len(outputToCache) == len(outputs).
Packages with two default outputs need 2/2 hits. In our lock that's gdk-pixbuf
(out + man), plus ffmpeg, gnumake, just, libheif, perl, pkg-config and qpdf so they lose twice as often.
IsInBinaryCache returns false, and InputAddressedPathForOutput
(internal/devpkg/package.go:604) aborts template rendering.
Concurrency makes a transient response much more likely. FillNarInfoCache
(narinfo_cache.go:51, called from internal/shellgen/flake_plan.go:43) uses an
unbounded errgroup one goroutine per package output. Our devbox.lock has 88
x86_64-linux outputs, so devbox opens 88 concurrent requests to cache.nixos.org from
one IP, every time.
The frustrating part: in CI, every one of those paths was already in the local nix
store from a restored cache. The build could not have needed the network at all.
What solution would you like?
In rough order of value:
Only 404 means absent. Treat 429/5xx/403 as inconclusive. Retry, or
surface a real error, rather than silently recording the package as missing.
What problem are you trying to solve?
A single transient non-200 from
cache.nixos.orgmakesdevbox runfail hard, evenwhen every store path is already present in the local nix store.
On a GitHub Actions runner, with the whole
/nix/storerestored from cache momentsearlier:
All six
gdk-pixbufx86_64-linux store paths in ourdevbox.lockreturn200fromcache.nixos.org, before and after the failure. Re-running the identical job, samecommit, same lockfile, succeeded with no changes. Out of 45 jobs in that CI run using
the same lockfile at the same moment, exactly one failed.
Root cause
fetchNarInfoStatusFromHTTPtreats any non-200 as "this path is not in the cache"(
internal/devpkg/narinfo_cache.go:228):A
429,503or403from the CDN is therefore recorded identically to a genuine404. There is no retry, and the request carries a 5s deadline(
narinfo_cache.go:216).That result then propagates as fact:
areExpectedOutputsInCacheOnce(narinfo_cache.go:89) requires every defaultoutput to be present:
len(outputToCache) == len(outputs).gdk-pixbuf(
out+man), plusffmpeg,gnumake,just,libheif,perl,pkg-configandqpdfso they lose twice as often.IsInBinaryCachereturns false, andInputAddressedPathForOutput(
internal/devpkg/package.go:604) aborts template rendering.Concurrency makes a transient response much more likely.
FillNarInfoCache(
narinfo_cache.go:51, called frominternal/shellgen/flake_plan.go:43) uses anunbounded
errgroupone goroutine per package output. Ourdevbox.lockhas 88x86_64-linux outputs, so devbox opens 88 concurrent requests to
cache.nixos.orgfromone IP, every time.
The frustrating part: in CI, every one of those paths was already in the local nix
store from a restored cache. The build could not have needed the network at all.
What solution would you like?
In rough order of value:
404means absent. Treat429/5xx/403as inconclusive. Retry, orsurface a real error, rather than silently recording the package as missing.
and it makes the common path both faster and network-independent. (Same theme as
Errors like "Too many requests" must be ignored if the package is already installed #2033.)
FillNarInfoCache, 88 simultaneous requests to onehost invites rate limiting.
Alternatives you've considered
A wrapper action.