Fixing “Illegal path references in fixed-output derivation” in Nix

Published by Philipp Schuster on

Screenshot: Nix build: "illegal path referenced in fixed-output derivation". The part on the top shows all Nix store paths that accidentally landed in the derivation (obtained by "grep")

The other day I was working with fixed-output derivations. After copying several files to $out, I was facing a “Illegal path references in fixed-output derivation error”. The only helpful reference on the internet I could find was the Nix source code on GitHub.

It took me a while to figure out what’s going on. You get this error when your fixed-output derivation places something in $out which contains a Nix store path! This can for example be a script with a (patched) shebang that (accidentally) landed there.

What happened in my case

I was packaging Limine and the ./bootstrap script performs several git clone invocations. Each git clone invocation creates .<repository>/git/hooks with a few example hooks. Each hook is a shell script starting with a shebang.. and Git automatically puts the binaries it finds in its PATH into the shebang, which on my NixOS system were all coming from the Nix store. That was a fun thing to debug!

The solution in that specific case is to remove all **/.git/hooks directories in that fixed-output derivation. 😂

Screenshot: Nix build: "illegal path referenced in fixed-output derivation". The part on the top shows all Nix store paths that accidentally landed in the derivation (obtained by "grep")
Screenshot: Nix build: “illegal path referenced in fixed-output derivation”. The part on the top shows all Nix store paths that accidentally landed in the derivation (obtained by “grep”)

Philipp Schuster

Hi, I'm Philipp and interested in Computer Science. I especially like low level development, making ugly things nice, and de-mystify "low level magic".

5 Comments

Rutherther · 2024-06-05 at 22:00

Hello Philipp,

I am thinking about your solution. It doesn’t seem to me your solution would be very robust. Since there should never be nix paths in the fixed output derivation, why not remove the source of the problems? In this case the source of the problems is fixup phase which does this shebang patching. Setting `dontFixup = true;` will disable it

    Philipp Schuster · 2024-06-11 at 18:54

    Hey! It is highly specific on the use-case. In my specific case, the git hooks were just junk, so removing them was correct. Sometimes however `dontFixup `true` or `dontPatchShebangs = true` might be necessary. The important take-away here is that if you get this error, you really have to check out where Nix store paths are in `$out` and if you need them at that point.

    Ben Millwood · 2024-10-11 at 03:09

    This actually isn’t shebang patching — `git clone` writes the example hooks like that in the first place. I guess it does something like $(realpath $(which bash)) and then writes that as the shebang line.

dns_issue · 2024-07-23 at 08:15

Haha, thanks for the post. Helped me fix my issue. I had the shebang line referencing bash from the /nix/store. I replaced it to: /etc/profiles/per-user//bin/bash. And it finally worked. Thanks man

Ben Millwood · 2024-10-11 at 03:06

I just created https://github.com/NixOS/nix/issues/11673 to talk about how to make this error easier to debug. I found it was extra painful in my case because I was doing `nix-build –keep-failed` but couldn’t find any path references in the build directory: it turned out I was writing them directly to `$out`, which isn’t the directory that’s kept. Lesson for me to do stuff in the build directory and then just copy it, as it makes `–keep-failed` more useful for stuff like this 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *