Skip to content

fetchurl, fetchgit: use __structuredAttrs = true and pass curlOptsList and sparseCheckout as lists#464475

Merged
ShamrockLee merged 3 commits intoNixOS:masterfrom
ShamrockLee:fetchurl-structuredAttrs
Dec 11, 2025
Merged

fetchurl, fetchgit: use __structuredAttrs = true and pass curlOptsList and sparseCheckout as lists#464475
ShamrockLee merged 3 commits intoNixOS:masterfrom
ShamrockLee:fetchurl-structuredAttrs

Conversation

@ShamrockLee
Copy link
Contributor

@ShamrockLee ShamrockLee commented Nov 24, 2025

While preserving existing interface, this PR enables fetchurl to take __struncuredAttrs. If specified as true, the curlOptsList will be passed to stdenvNoCC.mkDerivation as a list without stringification, facilitating its overriding with <pkg>.overrideAttrs.

To make fetchurl/builder.sh get the attributes when __structuredAttrs is true, it now sources $NIX_ATTRS_SH_FILE if presented.

As fetchFromGitHub switches between fetchurl and fetchgit with the same postFetch, this PR also converts the fetchgit-constructed FOD to use __structuredAttrs = true and passes sparseCheckout as a list. This way, out-of-tree projects that need to support multiple Nixpkgs releases can detect this series of changes based on __structuredAttrs.

Things done

  • Built on platform:
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • Tested, as applicable:
  • Ran nixpkgs-review on this PR. See nixpkgs-review usage.
  • Tested basic functionality of all binary files, usually in ./result/bin/.
  • Nixpkgs Release Notes
    • Package update: when the change is major or breaking.
  • NixOS Release Notes
    • Module addition: when adding a new NixOS module.
    • Module update: when the change is significant.
  • Fits CONTRIBUTING.md, pkgs/README.md, maintainers/README.md and other READMEs.

Add a 👍 reaction to pull requests you find important.

@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux. 10.rebuild-darwin: 11-100 This PR causes between 11 and 100 packages to rebuild on Darwin. 6.topic: fetch Fetchers (e.g. fetchgit, fetchsvn, ...) 6.topic: stdenv Standard environment labels Nov 24, 2025
@ShamrockLee ShamrockLee force-pushed the fetchurl-structuredAttrs branch 3 times, most recently from 13e79a4 to 82311b3 Compare November 24, 2025 07:06
@ShamrockLee
Copy link
Contributor Author

nixpkgs-review result

Generated using nixpkgs-review-gha

Command: nixpkgs-review pr 464475
Commit: 82311b3ddf90c3f75040100eb62bf4c94c40fd50 (subsequent changes)
Merge: 429195578e5acd6397df7f41fac0038d29b2c70e

Logs: https://github.com/ShamrockLee/nixpkgs-review-gha/actions/runs/19646047568


x86_64-linux

❌ 2 packages failed to build:
  • tests.fetchurl.header
  • tests.fetchurl.header-structured-attrs
✅ 62 packages built:
  • tests.fetchDebianPatch.libPackage
  • tests.fetchDebianPatch.simple
  • tests.fetchFirefoxAddon.simple (tests.fetchFirefoxAddon.overridden-source)
  • tests.fetchFromBitbucket.withEncodedWhitespace
  • tests.fetchFromBitbucket.withEncodedWhitespaceGit
  • tests.fetchFromBitbucket.withoutWhitespace
  • tests.fetchFromGitHub.dumb-http-signed-tag
  • tests.fetchFromGitHub.fetchTags
  • tests.fetchFromGitHub.leave-git
  • tests.fetchFromGitHub.rootDir
  • tests.fetchFromGitHub.simple
  • tests.fetchFromGitHub.sparseCheckout
  • tests.fetchFromGitHub.sparseCheckoutNonConeMode
  • tests.fetchFromGitHub.submodule-deep
  • tests.fetchFromGitHub.submodule-leave-git
  • tests.fetchFromGitHub.submodule-leave-git-deep
  • tests.fetchFromGitHub.submodule-simple
  • tests.fetchNextcloudApp.simple-sha256
  • tests.fetchNextcloudApp.simple-sha512
  • tests.fetchPypiLegacy.fetchSimple
  • tests.fetchgit.dumb-http-signed-tag
  • tests.fetchgit.fetchTags
  • tests.fetchgit.leave-git
  • tests.fetchgit.prefetch-git-no-add-path
  • tests.fetchgit.rootDir
  • tests.fetchgit.simple
  • tests.fetchgit.sparseCheckout
  • tests.fetchgit.sparseCheckoutNonConeMode
  • tests.fetchgit.submodule-deep
  • tests.fetchgit.submodule-leave-git
  • tests.fetchgit.submodule-leave-git-deep
  • tests.fetchgit.submodule-simple
  • tests.fetchgit.withGitConfig
  • tests.fetchpatch.decode
  • tests.fetchpatch.fileWithApostrophe
  • tests.fetchpatch.fileWithSpace
  • tests.fetchpatch.full
  • tests.fetchpatch.hunks
  • tests.fetchpatch.relative
  • tests.fetchpatch.simple
  • tests.fetchpatch2.decode
  • tests.fetchpatch2.fileWithApostrophe
  • tests.fetchpatch2.fileWithSpace
  • tests.fetchpatch2.full
  • tests.fetchpatch2.hunks
  • tests.fetchpatch2.relative
  • tests.fetchpatch2.simple
  • tests.fetchtorrent.http-link (tests.fetchtorrent.http-link-transmission)
  • tests.fetchtorrent.http-link-rqbit (tests.fetchtorrent.http-link-rqbit-flattened)
  • tests.fetchtorrent.http-link-rqbit-unflattened
  • tests.fetchtorrent.magnet-link (tests.fetchtorrent.magnet-link-transmission)
  • tests.fetchtorrent.magnet-link-rqbit (tests.fetchtorrent.magnet-link-rqbit-flattened)
  • tests.fetchtorrent.magnet-link-rqbit-unflattened
  • tests.fetchurl.hashedMirrors
  • tests.fetchurl.no-skipPostFetch
  • tests.fetchzip.hiddenDir
  • tests.fetchzip.postFetch
  • tests.fetchzip.simple
  • tests.haskell.cabalSdist.assumptionLocalHasDirectReference
  • tests.haskell.cabalSdist.localHasNoDirectReference
  • tests.testers.runCommand.bork
  • tests.testers.runCommand.dns-resolution

Error logs: `x86_64-linux`
tests.fetchurl.header
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-kz918smz4dji from any mirror

tests.fetchurl.header-structured-attrs
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-hj5mngsi3rq5 from any mirror


aarch64-linux

✅ 64 packages built:
  • tests.fetchDebianPatch.libPackage
  • tests.fetchDebianPatch.simple
  • tests.fetchFirefoxAddon.simple (tests.fetchFirefoxAddon.overridden-source)
  • tests.fetchFromBitbucket.withEncodedWhitespace
  • tests.fetchFromBitbucket.withEncodedWhitespaceGit
  • tests.fetchFromBitbucket.withoutWhitespace
  • tests.fetchFromGitHub.dumb-http-signed-tag
  • tests.fetchFromGitHub.fetchTags
  • tests.fetchFromGitHub.leave-git
  • tests.fetchFromGitHub.rootDir
  • tests.fetchFromGitHub.simple
  • tests.fetchFromGitHub.sparseCheckout
  • tests.fetchFromGitHub.sparseCheckoutNonConeMode
  • tests.fetchFromGitHub.submodule-deep
  • tests.fetchFromGitHub.submodule-leave-git
  • tests.fetchFromGitHub.submodule-leave-git-deep
  • tests.fetchFromGitHub.submodule-simple
  • tests.fetchNextcloudApp.simple-sha256
  • tests.fetchNextcloudApp.simple-sha512
  • tests.fetchPypiLegacy.fetchSimple
  • tests.fetchgit.dumb-http-signed-tag
  • tests.fetchgit.fetchTags
  • tests.fetchgit.leave-git
  • tests.fetchgit.prefetch-git-no-add-path
  • tests.fetchgit.rootDir
  • tests.fetchgit.simple
  • tests.fetchgit.sparseCheckout
  • tests.fetchgit.sparseCheckoutNonConeMode
  • tests.fetchgit.submodule-deep
  • tests.fetchgit.submodule-leave-git
  • tests.fetchgit.submodule-leave-git-deep
  • tests.fetchgit.submodule-simple
  • tests.fetchgit.withGitConfig
  • tests.fetchpatch.decode
  • tests.fetchpatch.fileWithApostrophe
  • tests.fetchpatch.fileWithSpace
  • tests.fetchpatch.full
  • tests.fetchpatch.hunks
  • tests.fetchpatch.relative
  • tests.fetchpatch.simple
  • tests.fetchpatch2.decode
  • tests.fetchpatch2.fileWithApostrophe
  • tests.fetchpatch2.fileWithSpace
  • tests.fetchpatch2.full
  • tests.fetchpatch2.hunks
  • tests.fetchpatch2.relative
  • tests.fetchpatch2.simple
  • tests.fetchtorrent.http-link (tests.fetchtorrent.http-link-transmission)
  • tests.fetchtorrent.http-link-rqbit (tests.fetchtorrent.http-link-rqbit-flattened)
  • tests.fetchtorrent.http-link-rqbit-unflattened
  • tests.fetchtorrent.magnet-link (tests.fetchtorrent.magnet-link-transmission)
  • tests.fetchtorrent.magnet-link-rqbit (tests.fetchtorrent.magnet-link-rqbit-flattened)
  • tests.fetchtorrent.magnet-link-rqbit-unflattened
  • tests.fetchurl.hashedMirrors
  • tests.fetchurl.header
  • tests.fetchurl.header-structured-attrs
  • tests.fetchurl.no-skipPostFetch
  • tests.fetchzip.hiddenDir
  • tests.fetchzip.postFetch
  • tests.fetchzip.simple
  • tests.haskell.cabalSdist.assumptionLocalHasDirectReference
  • tests.haskell.cabalSdist.localHasNoDirectReference
  • tests.testers.runCommand.bork
  • tests.testers.runCommand.dns-resolution

x86_64-darwin (sandbox = relaxed)

✅ 65 packages built:
  • tests.fetchDebianPatch.libPackage
  • tests.fetchDebianPatch.simple
  • tests.fetchFirefoxAddon.simple (tests.fetchFirefoxAddon.overridden-source)
  • tests.fetchFromBitbucket.withEncodedWhitespace
  • tests.fetchFromBitbucket.withEncodedWhitespaceGit
  • tests.fetchFromBitbucket.withoutWhitespace
  • tests.fetchFromGitHub.dumb-http-signed-tag
  • tests.fetchFromGitHub.fetchTags
  • tests.fetchFromGitHub.leave-git
  • tests.fetchFromGitHub.rootDir
  • tests.fetchFromGitHub.simple
  • tests.fetchFromGitHub.sparseCheckout
  • tests.fetchFromGitHub.sparseCheckoutNonConeMode
  • tests.fetchFromGitHub.submodule-deep
  • tests.fetchFromGitHub.submodule-leave-git
  • tests.fetchFromGitHub.submodule-leave-git-deep
  • tests.fetchFromGitHub.submodule-simple
  • tests.fetchNextcloudApp.simple-sha256
  • tests.fetchNextcloudApp.simple-sha512
  • tests.fetchPypiLegacy.fetchSimple
  • tests.fetchgit.dumb-http-signed-tag
  • tests.fetchgit.fetchTags
  • tests.fetchgit.leave-git
  • tests.fetchgit.prefetch-git-no-add-path
  • tests.fetchgit.rootDir
  • tests.fetchgit.simple
  • tests.fetchgit.sparseCheckout
  • tests.fetchgit.sparseCheckoutNonConeMode
  • tests.fetchgit.submodule-deep
  • tests.fetchgit.submodule-leave-git
  • tests.fetchgit.submodule-leave-git-deep
  • tests.fetchgit.submodule-simple
  • tests.fetchgit.withGitConfig
  • tests.fetchpatch.decode
  • tests.fetchpatch.fileWithApostrophe
  • tests.fetchpatch.fileWithSpace
  • tests.fetchpatch.full
  • tests.fetchpatch.hunks
  • tests.fetchpatch.relative
  • tests.fetchpatch.simple
  • tests.fetchpatch2.decode
  • tests.fetchpatch2.fileWithApostrophe
  • tests.fetchpatch2.fileWithSpace
  • tests.fetchpatch2.full
  • tests.fetchpatch2.hunks
  • tests.fetchpatch2.relative
  • tests.fetchpatch2.simple
  • tests.fetchtorrent.http-link (tests.fetchtorrent.http-link-transmission)
  • tests.fetchtorrent.http-link-rqbit (tests.fetchtorrent.http-link-rqbit-flattened)
  • tests.fetchtorrent.http-link-rqbit-unflattened
  • tests.fetchtorrent.magnet-link (tests.fetchtorrent.magnet-link-transmission)
  • tests.fetchtorrent.magnet-link-rqbit (tests.fetchtorrent.magnet-link-rqbit-flattened)
  • tests.fetchtorrent.magnet-link-rqbit-unflattened
  • tests.fetchurl.hashedMirrors
  • tests.fetchurl.header
  • tests.fetchurl.header-structured-attrs
  • tests.fetchurl.no-skipPostFetch
  • tests.fetchzip.hiddenDir
  • tests.fetchzip.postFetch
  • tests.fetchzip.simple
  • tests.haskell.cabalSdist.assumptionLocalHasDirectReference
  • tests.haskell.cabalSdist.localHasNoDirectReference
  • tests.testers.runCommand.bork
  • tests.testers.runCommand.dns-resolution
  • tests.testers.runCommand.nonDefault-hash

aarch64-darwin (sandbox = relaxed)

❌ 2 packages failed to build:
  • tests.fetchurl.header
  • tests.fetchurl.header-structured-attrs
✅ 63 packages built:
  • tests.fetchDebianPatch.libPackage
  • tests.fetchDebianPatch.simple
  • tests.fetchFirefoxAddon.simple (tests.fetchFirefoxAddon.overridden-source)
  • tests.fetchFromBitbucket.withEncodedWhitespace
  • tests.fetchFromBitbucket.withEncodedWhitespaceGit
  • tests.fetchFromBitbucket.withoutWhitespace
  • tests.fetchFromGitHub.dumb-http-signed-tag
  • tests.fetchFromGitHub.fetchTags
  • tests.fetchFromGitHub.leave-git
  • tests.fetchFromGitHub.rootDir
  • tests.fetchFromGitHub.simple
  • tests.fetchFromGitHub.sparseCheckout
  • tests.fetchFromGitHub.sparseCheckoutNonConeMode
  • tests.fetchFromGitHub.submodule-deep
  • tests.fetchFromGitHub.submodule-leave-git
  • tests.fetchFromGitHub.submodule-leave-git-deep
  • tests.fetchFromGitHub.submodule-simple
  • tests.fetchNextcloudApp.simple-sha256
  • tests.fetchNextcloudApp.simple-sha512
  • tests.fetchPypiLegacy.fetchSimple
  • tests.fetchgit.dumb-http-signed-tag
  • tests.fetchgit.fetchTags
  • tests.fetchgit.leave-git
  • tests.fetchgit.prefetch-git-no-add-path
  • tests.fetchgit.rootDir
  • tests.fetchgit.simple
  • tests.fetchgit.sparseCheckout
  • tests.fetchgit.sparseCheckoutNonConeMode
  • tests.fetchgit.submodule-deep
  • tests.fetchgit.submodule-leave-git
  • tests.fetchgit.submodule-leave-git-deep
  • tests.fetchgit.submodule-simple
  • tests.fetchgit.withGitConfig
  • tests.fetchpatch.decode
  • tests.fetchpatch.fileWithApostrophe
  • tests.fetchpatch.fileWithSpace
  • tests.fetchpatch.full
  • tests.fetchpatch.hunks
  • tests.fetchpatch.relative
  • tests.fetchpatch.simple
  • tests.fetchpatch2.decode
  • tests.fetchpatch2.fileWithApostrophe
  • tests.fetchpatch2.fileWithSpace
  • tests.fetchpatch2.full
  • tests.fetchpatch2.hunks
  • tests.fetchpatch2.relative
  • tests.fetchpatch2.simple
  • tests.fetchtorrent.http-link (tests.fetchtorrent.http-link-transmission)
  • tests.fetchtorrent.http-link-rqbit (tests.fetchtorrent.http-link-rqbit-flattened)
  • tests.fetchtorrent.http-link-rqbit-unflattened
  • tests.fetchtorrent.magnet-link (tests.fetchtorrent.magnet-link-transmission)
  • tests.fetchtorrent.magnet-link-rqbit (tests.fetchtorrent.magnet-link-rqbit-flattened)
  • tests.fetchtorrent.magnet-link-rqbit-unflattened
  • tests.fetchurl.hashedMirrors
  • tests.fetchurl.no-skipPostFetch
  • tests.fetchzip.hiddenDir
  • tests.fetchzip.postFetch
  • tests.fetchzip.simple
  • tests.haskell.cabalSdist.assumptionLocalHasDirectReference
  • tests.haskell.cabalSdist.localHasNoDirectReference
  • tests.testers.runCommand.bork
  • tests.testers.runCommand.dns-resolution
  • tests.testers.runCommand.nonDefault-hash

Error logs: `aarch64-darwin`
tests.fetchurl.header
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-x44mm00xk318 from any mirror

tests.fetchurl.header-structured-attrs
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-vcpgzcz10qw6 from any mirror

@ShamrockLee
Copy link
Contributor Author

nixpkgs-review result

Generated using nixpkgs-review-gha

Command: nixpkgs-review pr 464475 -p tests.fetchurl.header -p tests.fetchurl.header-structured-attrs
Commit: 82311b3ddf90c3f75040100eb62bf4c94c40fd50 (subsequent changes)
Merge: 113551a0c5b376c77a79e03e64ea609fbaaf721a

Logs: https://github.com/ShamrockLee/nixpkgs-review-gha/actions/runs/19647104942


x86_64-linux

❌ 2 packages failed to build:
  • tests.fetchurl.header
  • tests.fetchurl.header-structured-attrs

Error logs: `x86_64-linux`
tests.fetchurl.header
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-kz918smz4dji from any mirror

tests.fetchurl.header-structured-attrs
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-hj5mngsi3rq5 from any mirror


aarch64-linux

✅ 2 packages built:
  • tests.fetchurl.header
  • tests.fetchurl.header-structured-attrs

x86_64-darwin (sandbox = relaxed)

❌ 2 packages failed to build:
  • tests.fetchurl.header
  • tests.fetchurl.header-structured-attrs

Error logs: `x86_64-darwin`
tests.fetchurl.header
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-zyv8vsckdxzl from any mirror

tests.fetchurl.header-structured-attrs
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-ayv02jjpy99b from any mirror


aarch64-darwin (sandbox = relaxed)

❌ 2 packages failed to build:
  • tests.fetchurl.header
  • tests.fetchurl.header-structured-attrs

Error logs: `aarch64-darwin`
tests.fetchurl.header
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-x44mm00xk318 from any mirror

tests.fetchurl.header-structured-attrs
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
  0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
curl: (22) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
Warning: Problem : HTTP error. Will retry in 1 second. 3 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 2 seconds. 2 retries left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
Warning: Problem : HTTP error. Will retry in 4 seconds. 1 retry left.

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (22) The requested URL returned error: 503
error: cannot download source-salted-vcpgzcz10qw6 from any mirror

@ShamrockLee
Copy link
Contributor Author

The new test tests.fetchurl.header-structured-attrs is based on the existing test tests.fetchurl.header but with __structuredAttrs = true. However, tests.fetchurl.header itself seems flaky.

@nixpkgs-ci nixpkgs-ci bot added 12.approvals: 3+ This PR was reviewed and approved by three or more persons. and removed 12.approvals: 2 This PR was reviewed and approved by two persons. labels Dec 10, 2025
@ShamrockLee ShamrockLee added this pull request to the merge queue Dec 11, 2025
Merged via the queue into NixOS:master with commit 689380e Dec 11, 2025
36 of 38 checks passed
@ShamrockLee ShamrockLee deleted the fetchurl-structuredAttrs branch December 11, 2025 18:31
@panicgh
Copy link
Contributor

panicgh commented Dec 13, 2025

It seems this broke my fetcher. I bisected it and cd13136 is the first bad commit.

fetchFromGitLab {
  domain = "mydomain";
  private = true;
  varPrefix = "MYPREFIX";
  # to show curl SSL trust anchors:
  curlOptsList = [ "--verbose" ];

  # usual attrs
  owner = "owner";
  repo = "repo";
  rev = "v${version}";
  hash = lib.fakeHash;
}

curlOptsList = [ "--verbose" ] gives me a bit more information. Before cd13136, fetching works and curl reports:

source> * SSL Trust Anchors:
source> *   CAfile: /nix/store/m65dckzfgr1lr90g5v6jx0iynnz38nsk-nss-cacert-3.115/etc/ssl/certs/ca-bundle.crt

With/after cd13136, it fails with:

source> * SSL Trust Anchors:
source> *   OpenSSL default paths (fallback)
...
source> * SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
source>   0     0   0     0   0     0     0     0  --:--:-- --:--:-- --:--:--     0
source> * closing connection #0
source> curl: (60) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
source> More details here: https://curl.se/docs/sslcerts.html
source>
source> curl failed to verify the legitimacy of the server and therefore could not
source> establish a secure connection to it. To learn more about this situation and
source> how to fix it, please visit the webpage mentioned above.
source> Warning: Problem (retrying all errors). Will retry in 1 second. 3 retries left.
...

@chillcicada
Copy link
Contributor

Specifying the certificate in the curlOptsList can temporarily avoid this issue for the build. Perhaps we should revert this commit first.

src = fetchurl {
  # ...
  curlOptsList = [
    "--cacert"
    "${cacert}/etc/ssl/certs/ca-bundle.crt"
  ];
};

@MattSturgeon
Copy link
Contributor

Perhaps we should revert this commit first.

If a fix isn't immediately obvious then yes, we should revert for now. If we think we'll have a fix today, then I'm happy to hold off on reverting.

I suspect the certificate flags may be being defined somewhere in a way that assumes __structuredAttrs = false?

Personally I'd like to see a regression test added for "empty hash" FODs, so that we can know this is fixed and feel more confident about it not breaking again in the future.

@MattSturgeon
Copy link
Contributor

MattSturgeon commented Dec 13, 2025

With __structuredAttrs, SSL_CERT_FILE gets defined in $NIX_ATTRS_SH_FILE as:

declare SSL_CERT_FILE='/nix/store/m65dckzfgr1lr90g5v6jx0iynnz38nsk-nss-cacert-3.115/etc/ssl/certs/ca-bundle.crt'

I suspect without __structuredAttrs, derivation will export the variable instead of only declaring it?

Adding:

# Export SSL_CERT_FILE so curl can see it
export SSL_CERT_FILE="$SSL_CERT_FILE"

to builder.sh seems to fix the issue.

EDIT: #470503

@ShamrockLee
Copy link
Contributor Author

Sorry for my loose ends.

Packages with __structuredAttrs = true specifies environment variables from attributes via the env attribute. However, this is an incompatible change to the <pkg>.overrideAttrs interface.

AFAIK, we don't view <pkg>.overrideAttrs incompatibility as a "breaking/backward-incompatible change" in general. Still, <pkg>.overrideAttrs has been the only way to override fetchurl-constructed FODs long before these series of PR trying to fix and stabilize fetchurl's <pkg>.overrideAttrs.

How about we merge and backport @MattSturgeon's workaround (PR #470503) when backporting this PR, while leaving the env PR #470504 on the master branch?

@wolfgangwalther
Copy link
Contributor

How about we merge and backport @MattSturgeon's workaround (PR #470503) when backporting this PR, while leaving the env PR #470504 on the master branch?

I don't understand why to split this. #470504 seems like the correct fix to me, so we should just do that everywhere?

(I only looked at this from very, very, very far away - but handling environment variables correctly for structuredAttrs should be straight-forward)

@MattSturgeon
Copy link
Contributor

MattSturgeon commented Dec 13, 2025

#470504 is definitely the better fix.

I'm not an authority on this, but I assume we don't consider the SSL_CERT_FILE attr to be public API, so moving it into env shouldn't break any public API.

If you want to be extra safe, it could be mentioned in 26.05 release notes, and in the 25.11 backport it could be implemented as:

env.SSL_CERT_FILE = finalAttrs.SSL_CERT_FILE;

Or use my workaround. But either of those is probably overkill.

@ShamrockLee
Copy link
Contributor Author

I'm not an authority on this, but I assume we don't consider the SSL_CERT_FILE attr to be public API, so moving it into env shouldn't break any public API.

Ah, yes! That's a good point.

env.SSL_CERT_FILE = finalAttrs.SSL_CERT_FILE;

IIRC, stdenv.mkDerivation checks for repeated attributes it takes directly versus those via env. This will most likely fail the evaluation.

I don't understand why to split this. #470504 seems like the correct fix to me, so we should just do that everywhere?

Having a unified interface for future backports seems to be more important than preserving all local workarounds, especially since we don't guarentee such workarounds to be stable.

@panicgh
Copy link
Contributor

panicgh commented Dec 13, 2025

Sorry, this is way too advanced for me, I can only describe the symptoms I see from afar:
Both #470504 and #470503 fix the CA error in my case, but still changes to curlOpts in the netrcPhase are lost and probably this is another side effect of __structuredAttrs=true. For example for injecting additional headers to curl as in fetchgitlab doesn't work any more, and probably neither does passing creds via a netrc file (e.g. fetchgithub).
I see the correct args (--header @./private-token --netrc-file /build/netrc) passed if I echo curlOpts here, but then they are missing inside fetchurl/builder.sh.

@MattSturgeon
Copy link
Contributor

MattSturgeon commented Dec 13, 2025

fetchgitlab doesn't work any more

curlOpts="$curlOpts --header @./private-token"
is now incorrect variable expansion, as curlOpts is a bash array when __structuredAttrs is enabled.

It should be:

curlOpts+=(--header @./private-token)

EDIT: same for

curlOpts="$curlOpts --netrc-file $PWD/netrc"

which should be:

curlOpts+=(--netrc-file "$PWD"/netrc)

panicgh added a commit to panicgh/nixpkgs that referenced this pull request Dec 13, 2025
PR NixOS#464475 enables __structuredAttrs and makes curlOpts a bash array.
Consequently, it must be extended as such to be effective.

See also NixOS#464475 (comment)
@trofi
Copy link
Contributor

trofi commented Dec 14, 2025

The change cause $urls fallback handling failures (like in #466746 (comment) ). Proposed a trivial fix as:

@ShamrockLee
Copy link
Contributor Author

Why? We explicitly warn against curlOpts as a list.

@MattSturgeon
Copy link
Contributor

Did I misinterpret:

- $curlOpts
+ ${curlOpts[*]}

?

I assumed that meant that shell code should treat curlOpts as an array.

@ShamrockLee
Copy link
Contributor Author

Did I misinterpret:

- $curlOpts
+ ${curlOpts[*]}

?

I assumed that meant that shell code should treat curlOpts as an array.

That means it "can be" an array. We only warn (not throw) against it if users specify it as a list.

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

Labels

6.topic: fetch Fetchers (e.g. fetchgit, fetchsvn, ...) 10.rebuild-darwin: 11-100 This PR causes between 11 and 100 packages to rebuild on Darwin. 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux. 12.approvals: 3+ This PR was reviewed and approved by three or more persons.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants