Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/libstore/local-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,16 @@ LocalStore::LocalStore(ref<const Config> config)
schema upgrade is in progress. */
if (!config->readOnly) {
Path globalLockPath = dbDir + "/big-lock";
globalLock = openLockFile(globalLockPath.c_str(), true);
try {
globalLock = openLockFile(globalLockPath.c_str(), true);
} catch (SysError & e) {
if (e.errNo == EACCES || e.errNo == EPERM) {
e.addTrace({},
"This command may have been run as non-root in a single-user Nix installation,\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused by the tense ("may have been") here. Is the current command being run as non-root, or was a previous command run as non-root?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean the current command

Copy link
Member

@Mic92 Mic92 Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could probably also check check "isNonRootuser()" to make a more concrete error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in the general case where the file isn't owned by the current uid, we can add the hint that maybe you wanted to connect to a nix daemon instead.

Copy link
Contributor Author

@mkenigs mkenigs Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could say "you may want to start a Nix daemon", but the user doesn't really connect to the Nix daemon themselves so I don't think "you may want to connect to a Nix daemon instead" would be very helpful, because it's not actionable. Did you have something in mind?

"or the Nix daemon may have crashed.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would a daemon crash cause this issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had gleaned that from open issues, although maybe that's no longer the case? I just tried e.g. this reproducer and didn't get the error #3435 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do see the error if I sudo rm /nix/var/nix/daemon-socket/socket

}
throw;
}
}

if (!config->readOnly && !lockFile(globalLock.get(), ltRead, false)) {
Expand Down
3 changes: 2 additions & 1 deletion tests/functional/read-only-store.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ chmod -R -w $TEST_ROOT/var

# Make sure we fail on add operations on the read-only store
# This is only for adding files that are not *already* in the store
expectStderr 1 nix-store --add eval.nix | grepQuiet "error: opening lock file '$(readlink -e $TEST_ROOT)/var/nix/db/big-lock'"
# Should show enhanced error message with helpful context
expectStderr 1 nix-store --add eval.nix | grepQuiet "This command may have been run as non-root in a single-user Nix installation"
expectStderr 1 nix-store --store local?read-only=true --add eval.nix | grepQuiet "Permission denied"

# Test the same operations from before should again succeed
Expand Down
Loading