msteen/nix-prefetch
{ "createdAt": "2019-01-21T22:53:01Z", "defaultBranch": "master", "description": "Prefetch any fetcher function call, e.g. a package source", "fullName": "msteen/nix-prefetch", "homepage": null, "language": "Shell", "name": "nix-prefetch", "pushedAt": "2023-03-06T20:09:09Z", "stargazersCount": 142, "topics": [], "updatedAt": "2025-11-24T13:20:47Z", "url": "https://github.com/msteen/nix-prefetch"}nix-prefetch
Section titled “nix-prefetch”This tool can be used to determine the hash of a fixed-output derivation, such as a package source. This can be used to apply TOFU in Nixpkgs (see TOFU below). Besides determining the hash, you can also pass it a hash, and then it will validate it. It should work with any fetcher function (function that produces a fixed-output derivation), package derivations, or fixed-output derivations. In the case of the latter two (i.e. the derivations), it will reuse the arguments already passed to the fetcher.
The tool relies on an overlay to hijack calls made to the fetchers and to patch them to ignore insecure flags (those that disable certificate checking).
However it is possible that the particular fetcher used by a package was detected not to be a fetcher function, so for those edge cases there is the --fetcher option (see manpage).
Use cases for this tool include determining the hash of a new package version, automated update scripts, and inspecting the current argument passed to a fetcher.
Trust-On-First-Use (TOFU) is a security model that will trust that, the response given by the non-yet-trusted endpoint, is correct on first use and will derive an identifier from it to check the trustworthiness of future requests to the endpoint. An well-known example of this is with SSH connections to hosts that are reporting a not-yet-known host key. In the context of Nixpkgs, TOFU can be applied to fixed-output derivation (like produced by fetchers) to supply it with an output hash. https://en.wikipedia.org/wiki/Trust_on_first_use
To implement the TOFU security model for fixed-output derivations the output hash has to determined at first build. This can be achieved by first supplying the fixed-output derivation with a probably-wrong output hash, that forces the build to fail with a hash mismatch error, which contains in its error message the actual output hash.
Installation
Section titled “Installation”git clone https://github.com/msteen/nix-prefetch.gitcd nix-prefetchnix-env --install --file release.nixFeatures
Section titled “Features”-
Can work with any fetcher function, even those defined outside Nixpkgs.
-
Can work with any package that defines a
srcorsrcsattribute based on a fetcher. -
Supports the builtin fetchers, like
builtins.fetchurl. -
Automatically calls
callPackage { }whenever this is applicable. -
Monkey patches the fetchers (via an overlay) to not ignore certificate validity checking, to reduce the risk of man-in-the-middle (MITM) attacks when prefetching.
-
Automatically determines the default Git revision when none have been given.
-
Completions for
bashandzsh, including autocomplete for the fetcher arguments. -
Knows how fetchers are often built on top of other fetchers, and if this is the case, will report fetcher arguments as well in the autocomplete and help.
-
Not only allows passing string arguments to the fetcher, but any arbitrary Nix expression as well, e.g.
--count --expr 5. -
Boolean fetcher arguments can be given as flags, so you can do
--showURLsor--no-showURLsrather than--showURLs --expr trueor--showURLs --expr false, respectively. -
When the
--check-storeoption has been given, it will not redownload the source if you already have something installed that uses the source.
Limitations
Section titled “Limitations”-
If the fetcher used by a source is not packaged as a file, it is not possible to determine the original arguments passed to it.
For example the following will not work:
let fetcher = stdenv.mkDerivation { outputHash = "..."; };in stdenv.mkDerivation {src = fetcher {foo = 5;};}We would not be able to extract that
{ foo = 5; }was passed to the fetcher.Using import-from-derivation (IFD) or
builtins.exectogether with a rewriter based onrnixlikenix-update-fetchdoes, we could in theory even handle this case, but it is not worth implementing at the moment, considering this is an edge case I have yet to encounter.
Examples
Section titled “Examples”A package source:
$ nix-prefetch hello.srcThe fetcher will be called as follows:> fetchurl {> sha256 = "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i";> url = "mirror://gnu/hello/hello-2.10.tar.gz";> }
0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1iA package without a hash defined:
$ nix-prefetch '{ stdenv, fetchurl }: stdenv.mkDerivation rec { name = "test"; src = fetchurl { url = http://ftpmirror.gnu.org/hello/hello-2.10.tar.gz; }; }'The package test will be fetched as follows:> fetchurl {> sha256 = "0000000000000000000000000000000000000000000000000000";> url = "https://ftpmirror.gnu.org/hello/hello-2.10.tar.gz";> }
0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1iA package checked to already be in the Nix store thats not installed:
$ nix-prefetch hello --check-store --verboseThe package hello-2.10 will be fetched as follows:> fetchurl {> sha256 = "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i";> url = "mirror://gnu/hello/hello-2.10.tar.gz";> }
The following URLs will be fetched as part of the source:mirror://gnu/hello/hello-2.10.tar.gz
trying https://ftpmirror.gnu.org/hello/hello-2.10.tar.gz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0100 708k 100 708k 0 0 1072k 0 --:--:-- --:--:-- --:--:-- 1072k
0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1iA package checked to already be in the Nix store thats installed (i.e. certain the hash is valid, no need to redownload):
$ nix-prefetch git --check-store --verboseThe package git-minimal-2.18.1 will be fetched as follows:> fetchurl {> sha256 = "1dlq120c9vmvp1m9gmgd6m609p2wkgfkljrpb0i002mpbjj091c8";> url = "https://www.kernel.org/pub/software/scm/git/git-2.18.1.tar.xz";> }
1dlq120c9vmvp1m9gmgd6m609p2wkgfkljrpb0i002mpbjj091c8Passing a list rather than a string argument:
$ nix-prefetch fetchurl --urls --expr '[ mirror://gnu/hello/hello-2.10.tar.gz ]'The fetcher will be called as follows:> fetchurl {> sha256 = "0000000000000000000000000000000000000000000000000000";> urls = [ "mirror://gnu/hello/hello-2.10.tar.gz" ];> }
0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1iPassing an argument to the expression:
$ nix-prefetch '{ name }: pkgs.${name}' --argstr name fetchurl --url 'mirror://gnu/hello/hello-2.10.tar.gz'The fetcher will be called as follows:> fetchurl {> sha256 = "0000000000000000000000000000000000000000000000000000";> url = "mirror://gnu/hello/hello-2.10.tar.gz";> }
0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1iModify the Git revision of a call to fetchFromGitHub:
$ nix-prefetch openraPackages.engines.bleed --fetchurl --rev masterThe package openra-bleed-9c9cad1 will be fetched as follows:> fetchurl {> sha256 = "0100p7wrnnlvkmy581m0gbyg3cvi4i1w3lzx2gq91ndz1sbm8nd2";> url = "https://github.com/OpenRA/OpenRA/archive/master.tar.gz";> }
0sj8ac3vm8dwxzr7krq4gz4pdmzbiv31q20ca17jyzn0sxfddr81Hash validation:
$ nix-prefetch hello 0000000000000000000000000000000000000000000000000000The package hello-2.10 will be fetched as follows:> fetchurl {> sha256 = "0000000000000000000000000000000000000000000000000000";> url = "mirror://gnu/hello/hello-2.10.tar.gz";> }
error: A hash mismatch occurred for the fixed-output derivation output /nix/store/57fzizqf6658l22j247vka6ljbicvkzj-hello-2.10.tar.gz: expected: 0000000000000000000000000000000000000000000000000000 actual: 0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1iA specific file fetcher:
$ nix-prefetch hello_rs.cargoDeps --fetcher '<nixpkgs/pkgs/build-support/rust/fetchCargoTarball.nix>'The fetcher will be called as follows:> import /wheel/fork/nixpkgs/pkgs/build-support/rust/fetchCargoTarball.nix {> cargoUpdateHook = "";> name = "hello_rs-0.1.0";> patches = [ ];> sha256 = "0sjjj9z1dhilhpc8pq4154czrb79z9cm044jvn75kxcjv6v5l2m5";> sourceRoot = null;> src = /nix/store/m2a0y3phmxh5qi9q0i10an6rl15q1aig-nix-prefetch-0.1.0/contrib/hello_rs;> srcs = null;> }
0sjjj9z1dhilhpc8pq4154czrb79z9cm044jvn75kxcjv6v5l2m5List all known fetchers in Nixpkgs:
$ nix-prefetch --list --deepbuiltins.fetchGitbuiltins.fetchMercurialbuiltins.fetchTarballbuiltins.fetchurlelmPackages.fetchElmDepsfetchCratefetchDockerConfigfetchDockerLayerfetchFromBitbucketfetchFromGitHubfetchFromGitLabfetchFromRepoOrCzfetchFromSavannahfetchHexfetchMavenArtifactfetchNuGetfetchRepoProjectfetchTarballfetchbowerfetchbzrfetchcvsfetchdarcsfetchdockerfetcheggfetchfossilfetchgitfetchgitLocalfetchgitPrivatefetchgxfetchhgfetchipfsfetchmtnfetchpatchfetchs3fetchsvnfetchsvnrevisionfetchsvnsshfetchurlfetchurlBootfetchzipjavaPackages.fetchMavenjavaPackages.mavenPlugins.fetchMavenlispPackages.fetchurlpython27Packages.fetchPypipython36Packages.fetchPypirequireFileGet a specialized help message for a fetcher:
$ nix-prefetch fetchFromGitHub --helpPrefetch the fetchFromGitHub function call
Usage: nix-prefetch fetchFromGitHub [(-f | --file) <file>] [--fetchurl] [--force-https] [--arg <name> <value>] [--argstr <name> <value>] [-I <path>] [--option <name> <value>] [(-t | --type | --hash-algo) <hash-algo>] [(-h | --hash) <hash>] [--input <input-type>] [--output <output-type>] [--print-urls] [--print-path] [--compute-hash] [--check-store] [-s | --silent] [-q | --quiet] [-v | --verbose] [-vv | --debug] ... ([-f | --file] <file> | [-A | --attr] <attr> | [-E | --expr] <expr> | <url>) [<hash>] [--help | --autocomplete | --eval <expr>] [--] [--<name> ((-f | --file) <file> | (-A | --attr) <attr> | (-E | --expr) <expr> | <str>)] ...
Fetcher options (required): --owner --repo --rev
Fetcher options (optional): --curlOpts --downloadToTemp --executable --extraPostFetch --fetchSubmodules --githubBase --md5 --meta --name --netrcImpureEnvVars --netrcPhase --outputHash --outputHashAlgo --passthru --postFetch --private --recursiveHash --sha1 --sha256 --sha512 --showURLs --stripRoot --url --urls --varPrefixA package for i686-linux:
$ nix-prefetch '(import <nixpkgs> { system = "i686-linux"; }).scilab-bin'The package scilab-bin-6.0.1 will be fetched as follows:> fetchurl {> sha256 = "0fgjc2ak3b2qi6yin3fy50qwk2bcj0zbz1h4lyyic9n1n1qcliib";> url = "https://www.scilab.org/download/6.0.1/scilab-6.0.1.bin.linux-i686.tar.gz";> }
0fgjc2ak3b2qi6yin3fy50qwk2bcj0zbz1h4lyyic9n1n1qcliib