I’ve been advocating for Nix at my workplace for several months, and one of my colleagues has really embraced it. He’s a Go developer and has been using Nix to set up its home-manager profile based on ECPHP / Devs profile · GitLab and have some ephemeral development environments per project that include all necessary dependencies and tools, using direnv. The operating system we use is Ubuntu, not NixOS.
However, we’ve encountered a snag. Today, he tried to compile a small Go project, and although the compilation succeeded, he was unable to run the resulting binary:
$ go build
$ ./main
exec: failed to execute process ./main: the file exist and is executable. Check the interpreter or linker.
The default devShell defined in the project’s flake is trivial and just include go in the dependencies, nothing else.
I would greatly appreciate any insights or suggestions on how to resolve this issue but also understand it. Has anyone experienced similar problems with Go binaries in Nix? Any advice on troubleshooting or adjusting the configuration to ensure the binaries run correctly?
It’s my understanding that this means there was some problem with dynamic loading for the executable.
On NixOS, it’s typical to run into this error when executing a binary that was built on another system. Or when it’s linked against shared libraries built on another system.
I’d be curious what ldd ./main outputs.
For resolving this… I’d guess there’s some kind of library that should be added to the shell; or there’s some kind of mix of Nix and non-Nix compilers/libraries going on.
Running this code on my own NixOS laptop but also on my own Amazon Workspace (based on RedHat) works pretty fine. I don’t think the issue is related to Nix at all since the beginning.
(whereas, say, a “hello world” Go program doesn’t).
It’s nicer to be in a situation where you’ve got something that works & something that doesn’t work.
I’d check the output of ldd ./foo, which go, and perhaps stuff like the values of LD_LIBRARY_PATH; and compare/contrast between the system which works & the system which doesn’t.
To my understanding, cannot execute: required file not found suggests the interpreter just isn’t there / can’t be executed. I’d double-check /nix/store/35pq4hr29c3sl79lgfwgsvd9nwzyp4am-glibc-2.39-5/lib/ld-linux-x86-64.so.2 is there & that the user has permissions to execute it.
(Though I don’t know how go build could build a binary if those files aren’t there).
e.g. if you have some file bar.sh
#!/bin/nonexist
boop
and chmod +x ./bar.sh this file & try to run it, bash gives the same cannot execute: required file not found error. Whereas fish shell provides The file specified the interpreter '/bin/nonexist', which is not an executable command.
Similarly, using patchelf, running patchelf --set-interpreter /does/not/exist ./foo also gives similar errors: bash says bash: ./foo: cannot execute: required file not found, whereas fish shell says exec: Failed to execute process './foo': The file exists and is executable. Check the interpreter or linker?.
Perhaps using fish shell would provide a more helpful error.
I otherwise tried to reproduce the error with go build and go get on Ubuntu VMs in AWS, and was unable to reproduce it.