Skip to content

HttpBinaryCacheStore: Don't ignore 401/407 errors#461

Merged
edolstra merged 1 commit into
mainfrom
eelcodolstra/nix-399
May 18, 2026
Merged

HttpBinaryCacheStore: Don't ignore 401/407 errors#461
edolstra merged 1 commit into
mainfrom
eelcodolstra/nix-399

Conversation

@edolstra
Copy link
Copy Markdown
Collaborator

@edolstra edolstra commented May 18, 2026

The only reason it treats 403 errors as 404s is that S3 returns 403 for files that don't exist if the bucket is unlistable. But we don't want to ignore (and definitely shouldn't cache) 401/407 errors as "file not found".

This fixes "token expired" errors from cache.flakehub.com being silently ignored and cached. Now you get:

# nix build --dry-run /nix/store/qnfhg5anpfpr4il3jlp9bnkf6vhyzbnj-determinate-nix-3.20.0
error: unable to download 'https://cache.flakehub.com/qnfhg5anpfpr4il3jlp9bnkf6vhyzbnj.narinfo': HTTP error 401

       response body:
         {"code":401,"error":"Unauthorized","message":"Unauthorized.","request_id":"019e3a82-2474-7f80-8564-6e1bc2234654"}
don't know how to build these paths:
      /nix/store/qnfhg5anpfpr4il3jlp9bnkf6vhyzbnj-determinate-nix-3.20.0

i.e. it's a fatal error now unless you use --fallback.

Note: this can "break" systems that have expired/unauthenticated binary caches, but that is the intended behaviour without --fallback (we don't want fallback to building from source by default).

Motivation

Context

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced error handling for file transfer operations with improved distinction between authentication failures and permission errors. HTTP 401 and 407 responses now properly report as authentication errors, while 403 responses are reported as permission errors, providing clearer error messages when file transfer operations encounter access issues.

Review Change Stack

The only reason it treats 403 errors as 404s is that S3 returns 403
for files that don't exist if the bucket is unlistable. But we don't
want to ignore (and definitely shouldn't cache) 401/407 errors as
"file not found".

This fixes "token expired" errors from cache.flakehub.com being
silently ignored and cached. Now you get:

  # nix build --dry-run /nix/store/qnfhg5anpfpr4il3jlp9bnkf6vhyzbnj-determinate-nix-3.20.0
  error: unable to download 'https://cache.flakehub.com/qnfhg5anpfpr4il3jlp9bnkf6vhyzbnj.narinfo': HTTP error 401

         response body:

         {"code":401,"error":"Unauthorized","message":"Unauthorized.","request_id":"019e3a82-2474-7f80-8564-6e1bc2234654"}
  don't know how to build these paths:
    /nix/store/qnfhg5anpfpr4il3jlp9bnkf6vhyzbnj-determinate-nix-3.20.0

i.e. it's a fatal error now unless you use `--fallback`.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

📝 Walkthrough

Walkthrough

HTTP error classification is refined to distinguish authentication failures (401, 407) from authorization failures (403). A new Unauthorized enum variant is added to FileTransfer::Error, and the error mapping logic updates to use it while noting S3's 403 behavior for unlistable objects.

Changes

HTTP Error Status Code Classification

Layer / File(s) Summary
Error enum extension
src/libstore/include/nix/store/filetransfer.hh
FileTransfer::Error enum adds Unauthorized variant, enabling callers to distinguish authentication failures from authorization failures.
HTTP 401/403/407 status mapping
src/libstore/filetransfer.cc
HTTP 401 and 407 responses now map to Unauthorized; HTTP 403 maps to Forbidden with an explanatory comment about S3's behavior for missing or unlistable objects.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested reviewers

  • cole-h

Poem

A rabbit hops through status codes,
Finding truth in HTTP roads,
401 says "Who are you?"
403 says "That's not for you!"
Errors sorted, clear and bright, 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: distinguishing HTTP 401/407 errors (unauthorized) from 403 (forbidden), preventing them from being ignored as file-not-found errors.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch eelcodolstra/nix-399

Comment @coderabbitai help to get the list of available commands and usage tips.

@edolstra edolstra force-pushed the eelcodolstra/nix-399 branch from 6f28025 to c341e96 Compare May 18, 2026 10:01
@github-actions
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown

@github-actions github-actions Bot temporarily deployed to pull request May 18, 2026 10:06 Inactive
@edolstra edolstra added this pull request to the merge queue May 18, 2026
Merged via the queue into main with commit b181e64 May 18, 2026
29 checks passed
@edolstra edolstra deleted the eelcodolstra/nix-399 branch May 18, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants