Visitar URL original
Tarball cache: Use canonical URLs as cache keys by edolstra · Pull Request #16767 · NixOS/nix · GitHub
Skip to content

Tarball cache: Use canonical URLs as cache keys - #16767

Open
edolstra wants to merge 1 commit into
masterfrom
tarball-cache-canonical-keys
Open

edolstra wants to merge 1 commit into
masterfrom
tarball-cache-canonical-keys

Conversation

@edolstra

@edolstra edolstra commented Nov 5, 2026

Copy link
Copy Markdown
Member

Motivation

After nix flake update on a FlakeHub input like https://flakehub.com/f/NixOS/nixpkgs/0.2605, the next command missed the tarball cache and downloaded nixpkgs again. The cache entry was keyed on the redirect target as sent by the server (.../0.2605.1017737+rev-.../source.tar.gz), while the locked URL in flake.lock has %2Brev-. Similarly, fetchTree on a tarball URL containing a + never hit the cache.

Taken from DeterminateSystems#760.

Implementation

Use the canonical encoding of the URL (ParsedURL::to_string()) both for the cache lookup and for every URL in the redirect chain on insert. Existing cache entries for the original request URL stay valid, since those were already canonical.

Tests: a functional test for a + in a file:// tarball URL, and the tarball-flakes NixOS test now redirects to a + URL and checks that the locked URL is fetched from the cache with the web server stopped.


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

The same URL can reach downloadTarball_() in different encodings,
e.g. `+` vs. `%2B`. Cache keys were inconsistent about this:

* The lookup key was the URL string as passed in.

* The insert keys were the URLs in the redirect chain returned by
  the file transfer. The first one is `request.uri.to_string()`, which
  is re-encoded by ParsedURL (`+` becomes `%2B`), while the subsequent
  ones are curl's effective URLs, which are the `Location` headers
  verbatim.

This caused cache misses for FlakeHub flakes. E.g.
https://flakehub.com/f/NixOS/nixpkgs/0.2605 redirects to
https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.2605.1017737+rev-.../source.tar.gz,
which is cached with the `+`. However, the locked URL that ends up in
flake.lock goes through ParsedURL and so contains `%2B`. As a result,
the next command missed the cache and downloaded the tarball again.

Conversely, a tarball URL with a `+` passed to `fetchTree` was looked
up verbatim but inserted with `%2B`, so it never hit the cache.

The fix is to canonicalise all URLs used as cache keys via
ParsedURL::to_string(). Since the first URL in the redirect chain was
already canonical, existing cache entries for it remain valid.

Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added with-tests Issues related to testing. PRs with tests have some priority fetching Networking with the outside (non-Nix) world, input locking labels Nov 5, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fetching Networking with the outside (non-Nix) world, input locking with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants