Nix with Flakes does not recognise `$HOME/.config/nix/registry.json`

Hello,
I just performed a fresh install of NixOS (after I foolishly tried out ChromeOS w. Brunch on my main machine), but for some reason, Nix can’t recognise $HOME/.config/nix/registry.json even though it exists. Please help.

Thanks!

EDIT: For example, when I run nix flake show nixpkgs, it outputs error: getting status of /etc/nix/registry.json: Permission denied, when the expected is that it uses the one in ~/.config/nix. The result of nix registry list is the same error above. It is fine when I run nix flake show github:NixOS/nixpkgs.

My registry.json is here:

{
  "flakes": [
    {
      "exact": true,
      "from": {
        "id": "blender-bin",
        "type": "indirect"
      },
      "to": {
        "lastModified": 1687970107,
        "narHash": "sha256-vtebyFAdMjrGEcO4KheYH1rMqYRwjcZDb9MiC/y+i5k=",
        "path": "/nix/store/85kbrvpcv5gpsg5l2rf950zx4skq918r-source/blender",
        "rev": "b78d5c9dc93e738b3cccc5d31bd318b25dd91eea",
        "type": "path"
      }
    },
    {
      "exact": true,
      "from": {
        "id": "home-manager",
        "type": "indirect"
      },
      "to": {
        "lastModified": 1688302761,
        "narHash": "sha256-YIYKeX3YfoAIg9DTe6cl1ga87rDCNDZugdGuqsvEN30=",
        "path": "/nix/store/7idq9aj5jya6ffqvwb7y1gz1ij1zr2ga-source",
        "rev": "c85d9137db45a1c9c161f4718b13cc3bd4cbd173",
        "type": "path"
      }
    },
    {
      "exact": true,
      "from": {
        "id": "impermanence",
        "type": "indirect"
      },
      "to": {
        "lastModified": 1684264534,
        "narHash": "sha256-K0zr+ry3FwIo3rN2U/VWAkCJSgBslBisvfRIPwMbuCQ=",
        "path": "/nix/store/rg2s92f3y9qd9fhqvdl715zkj1i7dx1s-source",
        "rev": "89253fb1518063556edd5e54509c30ac3089d5e6",
        "type": "path"
      }
    },
    {
      "exact": true,
      "from": {
        "id": "nixos-hardware",
        "type": "indirect"
      },
      "to": {
        "lastModified": 1686838567,
        "narHash": "sha256-aqKCUD126dRlVSKV6vWuDCitfjFrZlkwNuvj5LtjRRU=",
        "path": "/nix/store/mf3nazm479fkbh9n3v7n73yrcvr8avi6-source",
        "rev": "429f232fe1dc398c5afea19a51aad6931ee0fb89",
        "type": "path"
      }
    },
    {
      "exact": true,
      "from": {
        "id": "nixpkgs",
        "type": "indirect"
      },
      "to": {
        "lastModified": 1688231357,
        "narHash": "sha256-ZOn16X5jZ6X5ror58gOJAxPfFLAQhZJ6nOUeS4tfFwo=",
        "path": "/nix/store/aw6kmwd8a02n2c1wysrfk2q31brlmqdz-source",
        "rev": "645ff62e09d294a30de823cb568e9c6d68e92606",
        "type": "path"
      }
    },
    {
      "exact": true,
      "from": {
        "id": "nixpkgs-unstable",
        "type": "indirect"
      },
      "to": {
        "lastModified": 1688231357,
        "narHash": "sha256-ZOn16X5jZ6X5ror58gOJAxPfFLAQhZJ6nOUeS4tfFwo=",
        "path": "/nix/store/aw6kmwd8a02n2c1wysrfk2q31brlmqdz-source",
        "rev": "645ff62e09d294a30de823cb568e9c6d68e92606",
        "type": "path"
      }
    },
    {
      "exact": true,
      "from": {
        "id": "nixvim",
        "type": "indirect"
      },
      "to": {
        "lastModified": 1688297518,
        "narHash": "sha256-27zsI/9OQkjkcz6/iXabraQNzJ8o4Z0G5MLv64zxZrc=",
        "path": "/nix/store/gdavfvhw7wd2wzyz8ch4bl6k219h9z64-source",
        "rev": "17ef1ed51face4aeb0663a49796de0088b0a61a6",
        "type": "path"
      }
    },
    {
      "exact": true,
      "from": {
        "id": "self",
        "type": "indirect"
      },
      "to": {
        "lastModified": 1688546032,
        "narHash": "sha256-JK4PVLaKQ+s1HRJO/c1OPYPs7cP18MR3hidLWmDNtBc=",
        "path": "/nix/store/jwngygpvmqiaraw09flg7j2jnc3c9323-source",
        "type": "path"
      }
    }
  ],
  "version": 2
}

What do you mean by “it doesn’t recognize it”? Does it not show up in the output of nix registry list? Do you get an error message? If you need help you have to provide more information.

Please post the full registry.json file and the output of nix registry list.

My nix.conf:

# WARNING: this file is generated from the nix.settings option in
# your Home Manager configuration at $XDG_CONFIG_HOME/nix/nix.conf.
# Do not edit it!
extra-experimental-features = nix-command flakes
flake-registry = .config/nix/registry.json

Ah ok, so that indicates that there is a file at /etc/nix/registry.json, but you’re not allowed to read it. Can you take a look and potentially delete that file?

This will not work. You will get an error like this when trying to interact with the registry:

warning: error: unable to download '.config/nix/registry.json': Couldn't resolve host name (6); retrying in 288 ms
warning: error: unable to download '.config/nix/registry.json': Couldn't resolve host name (6); retrying in 530 ms
warning: error: unable to download '.config/nix/registry.json': Couldn't resolve host name (6); retrying in 1216 ms
warning: error: unable to download '.config/nix/registry.json': Couldn't resolve host name (6); retrying in 2163 ms
error: download of '.config/nix/registry.json' was interrupted

The issue is that Nix interprets this as a URL, not a path. You have to supply an absolute path when using this option, as Nix will also not expand environment variables, so using ~ or $HOME will not work.

However, you probably don’t want to use this setting anyway!

First, this setting is designed to override the global registry and will prevent it from being loaded, so your registry list would look like this:

$ nix registry list
user   flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-23.05-darwin
user   flake:unstable github:NixOS/nixpkgs/nixpkgs-unstable
$

Second, the user registry is already searched for by default! See this excerpt from the nix registry manpage (emphasis me):

There are multiple registries. These are, in order from lowest to highest precedence:

  • The global registry, which is a file downloaded from the URL specified by the setting flake-registry. It is cached locally and updated automatically when it’s older than tarball-ttl seconds. The default global registry is kept in a GitHub repository.
  • The system registry, which is shared by all users. The default location is /etc/nix/registry.json. On NixOS, the system registry can be specified using the NixOS option nix.registry.
  • The user registry ~/.config/nix/registry.json. This registry can be modified by commands such as nix registry pin.
  • Overrides specified on the command line using the option --override-flake.

I assume you’re setting the nix.registry option manually with home-manager? Try removing it and rebuilding your home-manager configuration.

1 Like

OK, I think I know the reason why /etc/nix/registry.json is not readable by the regular user and that is because it is defined in my configuration.nix with this:

{
  nix.registry = lib.mapAttrs (_: value: {flake = value;}) inputs;
}

so that Nix3 commands would be consistent with my flaked configuration.
Because it is defined in my configuration.nix, the file is a symlink to a location in /nix which happens to be a location not readable by the normal user.

Do you know how to make this file readable while still maintaining this line?

So I guess you’re talking about a nix-store path like /nix/store/908...9vzp-registry? Those should absolutely be readable by all users. Very strange.

Could you post the output of readlink -f /etc/nix/registry.json and ls -la $(readlink -f /etc/nix/registry.json)? I hope this will give some insight into the permission issue itself.

I had to run these as root for these to work

# readlink -f /etc/nix/registry.json
/nix/store/f0wd6ksnlh7xyx0akhr3dig9fjx79mdj-etc-registry.json
# ls -la $(readlink -f /etc/nix/registry.json)
-r--r--r-- 2 root root 2225 Jan  1  1970 /nix/store/f0wd6ksnlh7xyx0akhr3dig9fjx79mdj-etc-registry.json

Thanks!

The store-path is read-only (as it should be), but it is readable by everyone. So I’m baffled why you could possibly get a permission denied error when reading it.

What do you get if you try to run cat /nix/store/f0wd6ksnlh7xyx0akhr3dig9fjx79mdj-etc-registry.json? Please post the exact error message. Maybe that is easier to search for.

For some reason the store-path is readable but the symlink isn’t. ¯\_(ツ )_/¯

This is very strange. Let’s try to drill down into it.

Could you run this command?

I gave the wrong command
(link=~/.nix-profile; while [[ -e $link ]]; do stat $link; echo '------'; cd $(dirname $link); link=$(realpath -se $(readlink $link)); done)
This would've been the correct one
(link=/etc/nix/registry.json; while [[ -e $link ]]; do stat $link; echo '------'; cd $(dirname $link); link=$(realpath -se $(readlink $link)); done)

This should show a full stat output of every symlink in this chain. You’ll probably have to run it as sudo. Please post the full output.

This is the output:

  File: /home/dch82/.nix-profile -> /home/dch82/.local/state/nix/profiles/profile
  Size: 45        	Blocks: 8          IO Block: 4096   symbolic link
Device: 0,44	Inode: 289         Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/   dch82)   Gid: (  100/   users)
Access: 2023-07-08 08:27:23.668998495 +0100
Modify: 2023-07-02 13:43:51.771339704 +0100
Change: 2023-07-02 13:43:51.771339704 +0100
 Birth: 2023-07-02 13:43:51.771339704 +0100
------
  File: /home/dch82/.local/state/nix/profiles/profile -> profile-5-link
  Size: 14        	Blocks: 8          IO Block: 4096   symbolic link
Device: 0,30	Inode: 89187       Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/   dch82)   Gid: (  100/   users)
Access: 2023-07-08 09:43:36.581997533 +0100
Modify: 2023-07-07 09:18:11.042658639 +0100
Change: 2023-07-07 09:18:11.042658639 +0100
 Birth: 2023-07-07 09:18:11.042658639 +0100
------
  File: /home/dch82/.local/state/nix/profiles/profile-5-link -> /nix/store/qvh0llkk4mm0bhr98wxgrkf8gvi73c2i-user-environment
  Size: 60        	Blocks: 8          IO Block: 4096   symbolic link
Device: 0,30	Inode: 56483       Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/   dch82)   Gid: (  100/   users)
Access: 2023-07-08 08:27:23.668998495 +0100
Modify: 2023-07-02 18:10:57.913299704 +0100
Change: 2023-07-02 18:10:57.913299704 +0100
 Birth: 2023-07-02 18:10:57.913299704 +0100
------
  File: /nix/store/qvh0llkk4mm0bhr98wxgrkf8gvi73c2i-user-environment
  Size: 120       	Blocks: 0          IO Block: 4096   directory
Device: 0,31	Inode: 2007691     Links: 1
Access: (0555/dr-xr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-07-02 18:10:57.844344369 +0100
Modify: 1970-01-01 01:00:01.000000000 +0100
Change: 2023-07-02 18:10:57.844344369 +0100
 Birth: 2023-07-02 18:10:57.836349548 +0100
------
realpath: missing operand
Try 'realpath --help' for more information.

Don’t know why realpath gave an error tho.

Ah sorry I forgot to replace the starting link after testing :see_no_evil: For your situation, you have to run the same command, but instead of ~/.nix-profile, you have to use /etc/nix/registry.json so we can see the link chain of that path. Could you try it again with that change?

That’s expected. The last iteration of this command prints the stat of a real path, not a symlink. Then it calls readlink on that path, which prints nothing, as that path isn’t a symlink, and so the input to realpath is empty, causing it to fail and the loop to abort.

This is the new output:

  File: /etc/nix/registry.json -> /etc/static/nix/registry.json
  Size: 29        	Blocks: 8          IO Block: 4096   symbolic link
Device: 0,30	Inode: 89091       Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-07-08 16:27:38.099450267 +0100
Modify: 2023-07-07 09:18:06.772658807 +0100
Change: 2023-07-07 09:18:06.772658807 +0100
 Birth: 2023-07-07 09:18:06.772658807 +0100
------
  File: /etc/static/nix/registry.json -> /nix/store/ddps9v3zkqyalb2zv5c3z4l8b0ya5hba-etc-registry.json
  Size: 61        	Blocks: 8          IO Block: 4096   symbolic link
Device: 0,31	Inode: 2678534     Links: 2
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-07-07 09:14:36.930422300 +0100
Modify: 1970-01-01 01:00:01.000000000 +0100
Change: 2023-07-07 09:14:36.962420744 +0100
 Birth: 2023-07-07 09:14:36.462445065 +0100
------
  File: /nix/store/ddps9v3zkqyalb2zv5c3z4l8b0ya5hba-etc-registry.json
  Size: 2225      	Blocks: 8          IO Block: 4096   regular file
Device: 0,31	Inode: 2667595     Links: 2
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-07-07 09:14:31.880683048 +0100
Modify: 1970-01-01 01:00:01.000000000 +0100
Change: 2023-07-07 09:14:37.647388317 +0100
 Birth: 2023-07-07 09:14:31.219719981 +0100
------
realpath: missing operand
Try 'realpath --help' for more information.

Hmm, that looks 100% fine. The two symlinks have 0777 rights, which is expected for symlinks, and you should be able to interact with them normally. I have no idea why you’re getting a permission denied error on /etc/nix/registry.json and no clue what else to check at this point.

Sorry.

Checked the permissions of /etc/nix and it reported a permission of 700. Maybe I configured something wrong and managed to mess up the permissions?

Ohh yeah that’s not good. /etc/nix should be something like 0555 or at least 0744. You could try to just add read permissions for everyone to that directory manually. Not sure if the next rebuild will overwrite this, though.

I have Impermanence setup, so it will probably get erased on reboot anyway.

How do I declaratively set permissions for /etc/nix?

This is an old thread, but as someone using impermanence who also ran into this issue, this can be solved with the NixOS impermanence module, where you can set permissions of persistent directories declarative with something like this

environment.persistent.<persistent directory>.directories = [
  (dir "/etc/nix" "root" "root" "u=rwx,g=rx,o=rx")
];

you still have to chmod /etc/nix once since the directory is now persisted. Not sure why the directory is created with 700 permissions set in the first place though, a solution to that would be nicer.