How is the resource 'sha256' calculated?

I was trying to setup simple nixos mailserver on a machine. The readme contains a snippet that is to be added to the configuration.nix, and then I’m supposed to update the sha256 hash to the correct one. This is what a nixos-rebuild test printed after I added the snippet in the readme:

[root@server:/etc/nixos]# nixos-rebuild test
error: hash mismatch in file downloaded from 'https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/v2.3.0/nixos-mailserver-v2.3.0.tar.gz':
  wanted: sha256:0000000000000000000000000000000000000000000000000000
  got:    sha256:0lpz08qviccvpfws2nm83n7m2r8add2wvfg9bljx9yxx8107r919
(use '--show-trace' to show detailed location information)
building Nix...
error: hash mismatch in file downloaded from 'https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/v2.3.0/nixos-mailserver-v2.3.0.tar.gz':
  wanted: sha256:0000000000000000000000000000000000000000000000000000
  got:    sha256:0lpz08qviccvpfws2nm83n7m2r8add2wvfg9bljx9yxx8107r919
(use '--show-trace' to show detailed location information)
building the system configuration...
error: hash mismatch in file downloaded from 'https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/v2.3.0/nixos-mailserver-v2.3.0.tar.gz':
  wanted: sha256:0000000000000000000000000000000000000000000000000000
  got:    sha256:0lpz08qviccvpfws2nm83n7m2r8add2wvfg9bljx9yxx8107r919
(use '--show-trace' to show detailed location information)

Before updating the sha, I downloaded the tarball manually and calculated it’s sha256sum, which came out different from the one calculated and expected by nix:

$ sha256sum ~/Downloads/nixos-mailserver-v2.3.0.tar.gz
e55c72dabca95fb5faf22ac15a08e58981a64989a302ce25e79a4f1df1d93fa5  /home/fctorial/Downloads/nixos-mailserver-v2.3.0.tar.gz

What is the reason for this discrepency?

1 Like

Part of the reason is that Nix likes to use a custom base32 notation to display the hash. You can use nix-hash to show it:

$ # Same hash as sha256sum, in base16:
$ nix-hash --flat --type sha256 /nix/store/l77avva6amxh74fq69v0j07czz1xianp-nixos-mailserver-v2.3.0.tar.gz
e55c72dabca95fb5faf22ac15a08e58981a64989a302ce25e79a4f1df1d93fa5
$ # Same hash again, but now displayed in our custom base32:
$ nix-hash --flat --base32 --type sha256 /nix/store/l77avva6amxh74fq69v0j07czz1xianp-nixos-mailserver-v2.3.0.tar.gz
199zv7qiskwswwjww0m3i54sd0c9wl45mh9aybxbapx9pkd74p75

The latter also matches the output of nix-prefetch-url https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/v2.3.0/nixos-mailserver-v2.3.0.tar.gz.

However, it doesn’t match the got: hash in your nixos-rebuild output. I can’t really explain that TBQH, so I’ll leave that part to someone else to answer :wink: .

The hashes from the error are probably the content hashes of the unpacked archives, while the manually calculated is the hash of the archive itself.

Also different representations are used between the error and manually calculated.

nix can display and consume hashes in various encodings, base 16, 32, and 64. sha256sum displays the hash in base 16.

Ah, indeed: it corresponds to

$ nix-prefetch-url --unpack https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/v2.3.0/nixos-mailserver-v2.3.0.tar.gz
0lpz08qviccvpfws2nm83n7m2r8add2wvfg9bljx9yxx8107r919

and

$ nix-hash --base32 --type sha256 /nix/store/kmw4363xxkcp9rlps4638f4rwpkhbkj2-nixos-mailserver-v2.3.0.tar.gz/
0lpz08qviccvpfws2nm83n7m2r8add2wvfg9bljx9yxx8107r919

Not sure if there’s a ‘nix-independent’ way to calculate the sha256 of a tree rather than of an archive, though

No, tree hashes are plain hashes over the NAR serialization.