The error comes from Nix trying to set up its own private mount namespace, which isn’t permitted in your current environment.
One thing worth trying is:
nix shell --store local
You can also try setting it for just that command:
NIX_CONFIG='store = local' nix shell
This makes Nix use the local store directly, but I’m not sure it’ll fix the namespace error with nix-coire. I’d try it first rather than changing your global nix.conf, since that could affect your setup outside the environment too.
I couldn’t find documentation for nix-coire, so if this doesn’t work, its README or the project’s author might be able to clarify how its isolation works.
It actually is nix-core. Sorry for the typo. It’s in the Fedora repository (here) and some documentation is here.
Trying to nix shell --store local results in the following:
antonio@X13:~/nix/devenv$ nix shell --store local
error: creating directory "/nix/store": Read-only file system
chillzone
(Rick The OldFart And **Private Tester**)
4
This is a hard kernel restriction, not a configuration issue. Since Linux 3.9, the kernel returns EPERM when CLONE_NEWUSER is requested and the caller is in a chroot environment (i.e., the caller’s root directory doesn’t match the mount namespace root). So once you’re inside a chroot, you cannot create another user namespace — and therefore cannot do a second unshare -r.
I’ve had success using something like this:(Never on a Atomic system though)
use pivot_root instead of chroot.
pivot_root actually changes the mount namespace root, so the kernel’s “is the caller in a chroot?” check doesn’t trigger. You can then create nested user namespaces freely (the kernel allows up to 32 levels).
A minimal pattern:
# Outer level
unshare -rm bash -c '
# pivot_root into the first rootfs
mkdir /mnt/newroot /mnt/oldroot
mount --bind /path/to/rootfs1 /mnt/newroot
cd /mnt/newroot
pivot_root . /mnt/oldroot
umount -l /mnt/oldroot
# Now you can create a SECOND user namespace inside
unshare -rm bash -c "
# pivot_root into the second rootfs
mkdir /mnt/newroot /mnt/oldroot
mount --bind /path/to/rootfs2 /mnt/newroot
cd /mnt/newroot
pivot_root . /mnt/oldroot
umount -l /mnt/oldroot
exec /bin/bash
"
'
Practical caveats:
You need mount --bind to make the target a proper mount point before pivot_root.
You must clean up the old root (umount -l /mnt/oldroot) to avoid leaking.
If you’re on a hardened system, check user.max_user_namespaces (or kernel.unprivileged_userns_clone on Debian/Ubuntu) — if set to 0, even the first unshare -U will fail regardless of nesting.
Alternative approach: avoid nesting entirely. If the goal is to run Nix inside a sandbox, do all the mount setup (including the Nix store) in a single namespace rather than trying to layer chroots.
I don’t really understand how Nix works, but it seems that develop does not bring flake-defined utilities in PATH.
antonio@X13:~/nix/devenv$ nix develop --command emacs
error (ignored): package 'nixpkgs#bashInteractive' does not provide a 'bin/bash'
/tmp/nix-shell.kGrXbO: line 2009: exec: emacs: not found
I’m using Nix to install Emacs in Fedora along with some additional toolings like ripgrep. Such are defined in ~/.nix/devenv/flake.nix. Inside of Emacs I want to be able to use Nix to make use of flakes for different projects. Thus the need for nested chroots: I can’t nix shell (or similar) since Emacs is itself ran with nix shell.
pivot_root seems like a complex setup. I might try it as a last resort.
yeah, my nix develop suggestion wasn’t the right fit here. It won’t automatically put Emacs from your tools flake on PATH.
The issue is that nix-core’s rootless chroot prevents Nix from creating the nested user namespace it needs. I don’t know of a reliable fix for nesting Nix this way on Silverblue.
The practical workaround is to run Emacs outside the chroot and let it use nix develop or direnv for each project. If you specifically need Emacs to run inside the chroot, pivot_root might be worth investigating