From af86d1c6efe3cf1391a473968aa742c6c2ec8be0 Mon Sep 17 00:00:00 2001 From: Mariappan Ramasamy <142216110+kp-mariappan-ramasamy@users.noreply.github.com> Date: Fri, 29 May 2026 10:56:18 +0800 Subject: [PATCH] nix: backport importCargoLock static.crates.io fix crates.io now rejects requests with curl/* User-Agent, returning HTTP 403 on `https://crates.io/api/v1/crates///download`. nixpkgs `fetchurl` calls curl with its default UA, so `rustPlatform.buildRustPackage` with `cargoLock.lockFile` (which routes through `importCargoLock` and fetches each crate tarball via `fetchurl`) fails on the first uncached crate, e.g.: trying https://crates.io/api/v1/crates/autocfg/1.5.1/download curl: (22) The requested URL returned error: 403 Reproduced UA blocklist: curl/8.5.0 -> 403 empty UA -> 302 cargo (...) -> 200 static.crates.io/* -> 200 (no UA gate) Override `pkgs.makeRustPlatform` (not `pkgs.rustPlatform.importCargoLock`): nixpkgs' `pkgs/development/compilers/rust/make-rust-platform.nix` constructs a fresh `importCargoLock` via `buildPackages.callPackage` against a hardcoded path to `pkgs/build-support/rust/import-cargo-lock.nix`, so overriding the top-level `rustPlatform.importCargoLock` is ignored by every call site that goes through `makeRustPlatform`. Both `nix/modules/native.nix` and `nix/modules/cross.nix` build their `rustPlatform` via `(pkgsCross.)makeRustPlatform { cargo = ...; rustc = ...; }`, so a top-level override silently misses macOS, Linux musl, and every cross target. Intercept `makeRustPlatform` instead and re-inject the patched `importCargoLock` via `overrideScope` on the returned scope so that `buildRustPackage` (resolved through `callPackage` against the scope's `self`) picks it up. The patched `import-cargo-lock.nix` is materialised at evaluation time via `builtins.toFile`/`builtins.readFile`/`builtins.replaceStrings` rather than `runCommand`. `runCommand` adds a build-time dependency on `/bin/sh` which fails on macOS sandbox builds with "requested impure path '/bin/sh', but it was not in allowed-impure-host-deps". `builtins.toFile` produces a store path purely at eval time with no derivation to build, sidestepping the sandbox check entirely. The one-line URL change inside `import-cargo-lock.nix` mirrors NixOS/nixpkgs#524985 byte-for-byte. Verified across all four flake systems by inspecting the rendered `cargo-vendor-dir.drv` graph - every crate tarball URL resolves to `https://static.crates.io/crates///download`: - x86_64-darwin (native + Darwin-to-Darwin cross) - aarch64-darwin (native + cross to x86_64-darwin) - x86_64-linux (native + gnu/musl cross) - aarch64-linux (native + gnu/musl cross) Upstream references: - rust-lang/crates.io#13482: original ticket (closed). Initially flagged python-requests/2.32.5+ UA; crates.io has since extended the blocklist to include curl/*. - NixOS/nixpkgs#512735 (merged 2026-04-26): sets `nixpkgs-fetchCargoVendor/2 (...)` UA and switches to `static.crates.io`. Only patches `fetchCargoVendor`. - NixOS/nixpkgs#524979 (closed 2026-05-27): tracking issue for the same 403 hitting `importCargoLock` (the path lightway uses). - NixOS/nixpkgs#524985 (merged 2026-05-27 to master): fix for `importCargoLock` - switches crate downloads to `https://static.crates.io/crates///download`, which has no UA gate. As of this commit the fix is on master only; `nixpkgs-unstable` (the channel this flake tracks at f9d8b65, 2026-05-25) does not yet contain it. Drop this overlay once `flake.lock` is bumped to a `nixpkgs-unstable` revision that includes NixOS/nixpkgs#524985. --- flake.nix | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 916f65f6..a703fde3 100644 --- a/flake.nix +++ b/flake.nix @@ -39,7 +39,44 @@ { _module.args.pkgs = import inputs.nixpkgs { inherit system; - overlays = [ inputs.rust-overlay.overlays.default ]; + overlays = [ + inputs.rust-overlay.overlays.default + # Backport NixOS/nixpkgs#524985 (merged 2026-05-27): switch + # `importCargoLock` to download crates from + # `https://static.crates.io/crates` instead of the API endpoint + # `https://crates.io/api/v1/crates/...`, which now returns HTTP 403 + # for `curl/*` User-Agents. See rust-lang/crates.io#13482 and + # NixOS/nixpkgs#524979. Drop this overlay once `flake.lock` is + # bumped to a `nixpkgs-unstable` revision containing the upstream + # fix. + # + # Override `makeRustPlatform` (not `rustPlatform.importCargoLock`): + # nixpkgs' `pkgs/development/compilers/rust/make-rust-platform.nix` + # constructs a fresh `importCargoLock` from a hardcoded file path + # via `buildPackages.callPackage`, so the top-level + # `rustPlatform.importCargoLock` is ignored by both native.nix and + # cross.nix (which both call `(pkgsCross.)makeRustPlatform`). + ( + final: prev: + let + patchedImportCargoLockFile = builtins.toFile "import-cargo-lock-static-crates-io.nix" ( + builtins.replaceStrings [ "https://crates.io/api/v1/crates" ] [ "https://static.crates.io/crates" ] + (builtins.readFile (prev.path + "/pkgs/build-support/rust/import-cargo-lock.nix")) + ); + in + { + makeRustPlatform = + args: + (prev.makeRustPlatform args).overrideScope ( + _: _: { + importCargoLock = prev.buildPackages.callPackage patchedImportCargoLockFile { + inherit (args) cargo; + }; + } + ); + } + ) + ]; config.allowUnfree = true; config.android_sdk.accept_license = true; };