nix: SubmitOutput + stale opaque registration permanently bricks floating-CA outputs (was not content-addressed)

Open
#201 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
55/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
cpp
Domain
build-system

Research direction

Start with DerivationBuilderImpl::checkSubmittedOutputs in src/libstore/build/derivation-builder-impl.cc, then read checkCAOutput in src/libstore/build/derivation-check.cc and UnixDerivationBuilderImpl::submitOutput for SubmitOutput. Reproduce the builder-rpc-v0 floating text-CA case with the shown nix build command; done means a pre-existing opaque registration no longer causes OutputRejected and the output is registered with CA metadata.

Written by the indexing model from the issue text.

Description

Filing here because Mic92/nix-1 (where the defect lives) has issues disabled. Verified present in the fork at repkgs @ e6c24e7 and on main.

checkSubmittedOutputs trusts the existing store registration of a submitted output path as-is. If that path is already valid without CA metadata (e.g. left behind by an interrupted build or an RPC add), every later build of the producer fails with OutputRejected — forever, until the path is manually deleted.

Repro

builder-rpc-v0 producer with a floating text-CA output (builder/fetch/dyn-drv.nu collect, submitted via jig nix-store submit, op 1000), resolved through an ssh-ng store:

$ nix build --store 'ssh-ng://builder' --eval-store auto \
    '/nix/store/ygvl9684wa5ch3c8n60xkr9bmag4jsbq-cargo-vendor.drv.drv^out' \
    --no-link --print-build-logs
building '/nix/store/4vr0s4y7hj5804di7a1fh4swzlpf5lwg-cargo-vendor.drv.drv'...
cargo-vendor.drv> cargo-vendor: 92 entries, 46 inputs -> /nix/store/j6px9jz552gsyffyxvj6c0826l1yhnxr-cargo-vendor.drv
error: floating content-addressing derivation '...drv.drv' output 'out' (at '...drv') was not content-addressed
error: build of resolved derivation '...drv.drv' failed

The producer itself succeeds (it prints the output path); only post-build validation fails. (4vr0 vs ygvl is just content-identity placeholder resolution on the remote side; output content is identical.)

State evidence on the build host — output registered without CA:

$ nix path-info --json --store 'ssh-ng://builder' /nix/store/j6px9....drv
{"/nix/store/j6px9....drv": {"ca": null, ...}}

After nix store delete --store 'ssh-ng://builder' /nix/store/j6px9....drv, the exact same build succeeds and re-registers the path with ca = text:sha256:05hr... (identical hash as on the originating machine, where it always worked).

Root cause (fork)

DerivationBuilderImpl::checkSubmittedOutputs (src/libstore/build/derivation-builder-impl.cc) does:

infos.emplace(outputName, *localStore.queryPathInfo(outputPath));
...
checkOutputs(localStore, drvPath, drv, drvOptions.outputChecks, infos);

and checkCAOutput (src/libstore/build/derivation-check.cc) throws OutputRejected when !info.ca.has_value(). Nothing on the submit path (UnixDerivationBuilderImpl::submitOutput, op SubmitOutput = 1000) ensures the output is registered with its declared CA method, and nothing re-hashes the content at finalisation — a pre-existing opaque registration wins and poisons the path permanently.

Note e6c24e7 ("replace the build trace of a deleted output on rebuild") handles the deleted-output case; the present-but-opaque case still bricks the build.

Suggested fix (fork)

Either make submit register the output with the CA method declared in the submitted derivation (outputs: {out: {hashAlgo: "text:sha256"}} is known at submit time), or make finalisation fall back to hashing the submitted content when the existing registration lacks CA info, instead of failing unconditionally.

Dominant language
Nushell
Stars
84
Forks
7
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Similar issues

More Build System issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.