Builtins.fetchurl vs nixpkgs.fetchurl

When trying to fetch a dependency from a private S3 bucket with fetchurl, it seemed like s3:// URLs were supposed to be supported, but I was seeing the error message

curl: (1) Protocol "s3" not supported or disabled in libcurl

After a lot of confusion, discovered that (import <nixpkgs> {}).fetchurl is a fixed-output derivation invoking curl, while builtins.fetchurl is an entirely different implementation built in to nix. Only the builtins one supports S3.

Other differences seem to be:

  • nixpkgs.fetchurl supports SRI hash, while builtins requires sha256
  • nixpkgs.fetchurl uses .netrc via curl, while builtins does not

I could find very little documentation on these, so I wanted to open a thread to clarify, and to put some keywords on a page for the next person to find when googling this.

Why do both exist, and besides the feature discrepancies, when should one or the other be used?

1 Like

The most important difference I know of is that builtins.fetchurl is not a derivation. To be specific, the download happens during evaluation, not during building, so that means importing from it is not IFD. builtins.toFile vs pkgs.writeText is similar.

1 Like