Proxmox LXC Bind Mounts: UID/GID Mapping, Permissions, NFS, and Backups

16 min read

Proxmox LXC bind mount permission errors follow a predictable pattern: the mount shows up fine, ls even lists the files, but the application inside the container gets Permission denied or sees everything owned by nobody:nogroup. The mount worked. The ownership translation didn’t.

That translation problem sits in one of four places: host filesystem ownership, the container’s user namespace mapping, remote-filesystem semantics for NFS or CIFS, or the actual UID the application runs as inside the container. Solving a Proxmox LXC bind mount problem means working through all four, in the order that actually resolves fastest – the same ownership model applies whether the container is running a media server, a database, or a Docker workload that expects specific host paths.

Quick answer

Fixing a bind mount permission problem starts with an unprivileged LXC container and existing host directories added through an mpX bind mount. First verify the directory or remote share on the Proxmox host, then compare numeric ownership with the UID/GID the application uses inside the CT. With the default mapping, CT UID 1000 commonly appears as host UID 101000. Proxmox VE 9.2 adds per-mount idmap= support for compatible filesystems, but it is not a universal fix for NFS or CIFS. Bind-mounted data is never included in vzdump, so back it up separately.

SymptomFirst check
Files appear as nobody:nogroupCompare numeric ownership with the CT namespace map
Host can write, application cannotCheck the actual application UID/GID and the ACL/mode bits
Works, then breaks after a node rebootConfirm the NFS/CIFS share is really mounted before CT startup
CT fails to start after adding idmap=Check filesystem support and the mount/start logs
Migration is blocked or the data looks wrongConfirm identical path and shared=1; treat migration as offline
Restore succeeds but data is missingRestore the bind-mounted data separately from the CT
TL;DR
  • An mpX host-path bind mount is the preferred configuration method, but it is not a Proxmox-managed storage volume – Proxmox tracks the config entry, not the data behind it
  • nobody:nogroup usually means the source UID/GID can’t be represented through the container’s active mapping – confirm the numeric IDs before changing anything, and rule out a genuinely-owned UID 65534 or a deliberate NFS squash result
  • Proxmox VE 9.2 added per-mount idmap= for unprivileged containers on filesystems that support ID-mapped mounts – don’t assume NFS or CIFS qualifies without testing
  • Start NFS troubleshooting with numeric-identity translation; root_squash, all_squash, anonymous IDs, and export ACLs only matter once you know which identity actually reaches the server
  • Bind-mount contents are never included in a vzdump backup, regardless of the backup flag – back up the source separately, and expect root-level administration for restoring the mount-point definition itself
  • Never fix a permission mismatch with a recursive chown -R across shared storage before confirming the mapping

Bind Mount, Storage-Backed Mount, or Raw LXC Entry?

The right method depends on what’s actually behind the path – a decision worth making before touching any config file.

RequirementRecommended methodWhy
Additional CT volume eligible for Proxmox-managed backup, snapshot, and replicationStorage-backed mpX volumeManaged by Proxmox storage
Existing host directoryHost-path bind mount through mpXClear CT configuration, simpler lifecycle than raw entries
Host-mounted NFS/CIFS shareMount on host, then mpX bind mountCentralizes network mount and credentials
Per-mount ownership translationidmap= on Proxmox VE 9.2+Avoids changing the whole CT’s mapping
Low-level mount option mpX can’t expresslxc.mount.entryAdvanced exception, not a starting point
Complex filesystem, kernel module, or ACL modelVMCleaner ownership and kernel boundary

Actual backup and replication behavior depends on the storage backend and mount-point options: a storage-backed mount point still needs backup=1 to be included in vzdump, and snapshot/replication support depends on the backend and replication configuration – it isn’t automatic just because the volume is storage-backed.

mp0 through mp255 are configuration slots, not a guarantee of anything about the data behind them. An mpX entry can point to a storage-backed Proxmox volume, a host-path bind mount, or a device mount – and only the first of those is actually managed by Proxmox storage. Use an mpX entry by default because Proxmox understands the container path, read-only state, sharing flag, and related lifecycle metadata. But an mpX entry pointing to /mnt/... is still a host-path bind mount: Proxmox does not manage, snapshot, replicate, or back up the data behind that path. Creating or restoring arbitrary bind/device mount points is also restricted to root-level administration – a delegated Proxmox role that can manage normal guest disks may still be unable to restore a CT backup containing a host-path bind mount. Apply bind-mount and mapping changes with the CT stopped when possible; some mount-point changes aren’t safely hot-applied, and a restart is required before judging the result. That distinction drives most of what follows in this guide.

How Unprivileged LXC Ownership Works

This is the mechanism behind almost every bind mount permission issue. Unprivileged containers use Linux user namespaces to remap UID/GID ranges: a process can be root inside the container’s namespace while being an ordinary, unprivileged user on the host. Per the official Proxmox Container Toolkit documentation, in a default unprivileged CT, UID 0 commonly maps to host UID 100000, and UID 1000 to host UID 101000 – a fixed offset applied across the whole ID range. The 100000 offset is the normal Proxmox default, not a universal constant – custom global mappings, restored configurations, or manually edited subuid/subgid ranges can produce different values, so verify the active map before changing ownership based on this number alone.

CT modelContainer UID 0 on hostBind-mount convenienceSecurity position
UnprivilegedRemapped, commonly to 100000Requires UID/GID alignmentRecommended default
PrivilegedHost UID 0Simpler ownership behaviorWeaker isolation; trusted workloads only

A bind-mounted directory keeps its original host-side ownership. If its numeric UID or GID cannot be represented through the container’s active mapping, Linux exposes the overflow identity, commonly shown as nobody:nogroup. That is usually the expected overflow behavior – but confirm the underlying file isn’t genuinely owned by UID/GID 65534, and that NFS squash rules aren’t deliberately producing the anonymous identity, before treating it as a mapping-only problem.

Find the actual application UID/GID before touching anything:

# Identify the application process and its UID/GID inside the CT pct exec 200 -- ps -eo user:20,uid,gid,comm,args pct exec 200 -- id appuser # Inspect the container's own user namespace mapping (not the host shell's) pct exec 200 -- cat /proc/1/uid_map pct exec 200 -- cat /proc/1/gid_map

Why operators get this wrong: they check /proc/self/uid_map on the host shell, which shows the host process’s own mapping, not the container’s. The CT’s mapping has to be read from inside the CT’s namespace, via pct exec, or it tells you nothing about what the container actually sees.

Choose a UID/GID Mapping Strategy

Every ownership fix falls into one of these approaches, in order of how much they change and how much they’re worth reaching for.

Strategy A – the default shifted mapping. CT UID 0 maps to host UID 100000, CT UID 1000 to host UID 101000, no custom config needed. Simplest default – works well for a dedicated local dataset chowned to match the offset. After confirming the application’s UID/GID and the CT’s default offset, create a dedicated source directory with matching ownership rather than recursively changing an existing tree:

# Create a dedicated empty source with mapped ownership install -d -m 0750 -o 101000 -g 101000 /mnt/bindmounts/appdata pct set 200 -mp0 /mnt/bindmounts/appdata,mp=/data

101000 is only correct when CT UID/GID 1000 maps through the default 100000 offset – verify the active uid_map/gid_map first. The tradeoff with Strategy A is host and NAS-side ownership living at unusual, high numeric IDs.

Strategy B – Proxmox VE 9.2 per-mount idmap=. Proxmox VE 9.2 introduced idmap= for individual rootfs and mpX mount points, built on the kernel’s ID-mapped mounts mechanism – it customizes translation for one mount without touching the container’s global lxc.idmap. It only works for unprivileged containers, unmapped IDs fall back to lxc.idmap, and the filesystem must actually support ID-mapped mounts – don’t assume a network filesystem does without testing.

The option takes one idmap= field with semicolon-separated entries in type:container-id:disk-id:range-size format – confirm the host is actually on Proxmox VE 9.2 or later before relying on this syntax:

mp0: /mnt/bindmounts/appdata,mp=/data,idmap=u:1000:1000:1;g:1000:1000:1

This maps container UID 1000 to disk UID 1000 and container GID 1000 to disk GID 1000, covering one ID each; everything else falls back to the container’s default mapping. Map only the identities the workload actually requires, and keep the source path narrowly scoped – don’t map a container identity to a sensitive disk UID merely to make ownership look convenient. On the CLI, quote the whole mount-point argument so the shell doesn’t interpret the semicolon:

pct set 200 -mp0 '/mnt/bindmounts/appdata,mp=/data,idmap=u:1000:1000:1;g:1000:1000:1'

Stop the CT, record the original mpX line, apply the mapping, start, then verify numeric ownership and actual application operations – don’t judge from ls -l alone. Don’t reuse 100000 here by habit – inspect the real source owner and the application’s actual UID/GID first, then build the mapping around those two numbers:

stat -c '%u:%g %n' /mnt/bindmounts/appdata

If the mount fails after adding idmap=, check for the specific failure rather than guessing:

pct start 200 journalctl -b | grep -Ei 'idmap|mount_setattr|operation not supported|invalid argument'

If it fails only after the mapping is added, remove it and solve the identity problem at the NFS or CIFS layer instead – not every filesystem supports ID-mapped mounts, and forcing it isn’t the fix.

When global lxc.idmap is required. Global mapping changes every filesystem view in the container, not just one mount point, and needs complete, non-overlapping UID/GID ranges matched against host /etc/subuid//etc/subgid. An incomplete or overlapping map can prevent the CT from starting, or expose a host identity too broadly – so this guide doesn’t offer a universal copy-paste map. Use per-mount idmap= on 9.2+ where the default offset doesn’t fit, or build and test a mapping plan specific to the exact CT and service identities.

Recommended order: Strategy A first, Strategy B second on Proxmox VE 9.2+, and a validated global mapping only as an advanced fallback when neither fits.

Proxmox LXC bind mount UID translation comparing the default namespace offset with per-mount idmap

Create a Safe Host-Path Bind Mount

Setting up a Proxmox LXC bind mount safely starts before the first pct set command – with the source path itself.

Failure scenario

Security rule: create a dedicated hierarchy such as /mnt/bindmounts/<service>. Never expose broad host system directories like /, /etc, or /var to a container, and don’t use a source path containing symlinks. A bind mount exposes the same underlying host or remote files rather than creating a separate storage copy – access is still subject to UID/GID mapping, mode bits, supported ACLs, mount flags, AppArmor, and remote-server policy, but Proxmox doesn’t create an independent data boundary around the mounted path.

mkdir -p /mnt/bindmounts/media pct set 200 -mp0 /mnt/bindmounts/media,mp=/media,ro=1

Starting read-only is a reasonable default for media libraries and similar read-heavy workloads. Enable writes only where the application actually requires them.

NFS into Proxmox LXC

NFS is where a Proxmox LXC bind mount problem most often gets misdiagnosed. In the default host-mounted, unprivileged-CT design, start with numeric-identity translation rather than export policy. When NFS is mounted on the Proxmox host and then bind-mounted into a default unprivileged CT, the NFS client sends the effective host-side numeric identity – CT UID 0 normally arrives at the NFS layer as host UID 100000, not as UID 0. Per the Linux NFS exports manual, root_squash specifically maps requests from UID/GID 0 to an anonymous identity, so it only applies to requests that actually reach the server as UID/GID 0 – all_squash, anonymous IDs, NFSv4 identity mapping, and export ACLs can still be the primary cause even when root_squash itself isn’t relevant.

First determine which host-side UID/GID the container process becomes, then compare that value with ownership and export policy on the NFS server:

  1. Identify the application UID/GID inside the CT
  2. Inspect the same file numerically on the Proxmox host
  3. Inspect ownership numerically on the NFS server
  4. Confirm NFS version and NFSv4 ID-mapping configuration where relevant
  5. Check export options, including root_squash, all_squash, anonuid, and anongid
  6. Test with a dedicated directory rather than changing the whole export

Don’t reach for no_root_squash as a routine permissions fix – it expands the trust given to the NFS client and should only be used when the security implications are a deliberate choice, not a shortcut.

CIFS/SMB into Proxmox LXC

A Proxmox LXC bind mount over CIFS fails for a different reason than NFS usually does. CIFS mount options control what ownership looks like from the client side, and it’s worth distinguishing normal behavior from forced behavior. Per the mount.cifs manual, uid= and gid= provide the local ownership used when the server doesn’t supply usable Unix ownership information. forceuid and forcegid go further and tell the client to ignore whatever ownership the server returns, forcing the specified IDs instead. file_mode and dir_mode affect the client-side mode the mount presents. All CT processes accessing this share ultimately operate through the SMB credentials used for the host mount – local UID presentation doesn’t create separate server-side SMB identities, and the server’s own credentials and ACLs still decide whether an operation is actually allowed.

For an application running as UID/GID 1000 inside a default unprivileged CT, the corresponding host IDs are commonly 101000:101000 – not 1000:1000, which is the mistake that produces nobody:nogroup even when the mount options look reasonable. Let the client negotiate the highest supported SMB2+ dialect unless your environment specifically requires and has tested a fixed version:

//nas/share /mnt/cifs/share cifs credentials=/root/.cifs-cred,_netdev,uid=101000,gid=101000,forceuid,forcegid,file_mode=0660,dir_mode=0770 0 0

Treat 101000 as an example based on the default offset, not a universal constant – verify the CT’s actual mapping first. Confirm both sides after mounting:

stat -c '%u:%g %A %n' /mnt/cifs/share pct exec 200 -- stat -c '%u:%g %A %n' /share

Lock down the credentials file itself while you’re there:

chown root:root /root/.cifs-cred chmod 600 /root/.cifs-cred

noperm disables local client permission checks entirely and shouldn’t be treated as a default fix – it removes a check rather than resolving the mismatch underneath it.

Make Sure the Remote Filesystem Is Really Mounted

A network bind mount adds one more failure mode local storage doesn’t have. If an NFS or CIFS mount is unavailable when the CT starts, the host path can still exist as an ordinary empty directory – and the container happily writes into that empty local directory instead of the intended remote share. This is one of the most operationally costly failure modes in a host-first bind-mount design, precisely because nothing visibly errors. Confirm the underlying network path to the NAS is actually up before assuming the mount itself is the problem, and check more than the directory’s existence – confirm the actual filesystem type, source, and target:

findmnt -T /mnt/nfs/media -n -o FSTYPE,SOURCE,TARGET mountpoint -q /mnt/nfs/media

A plain test -d or a manual mountpoint -q /mnt/nfs/media && pct start 200 check is useful for a one-off test, but neither is a persistent boot-time control, and a .automount unit by itself isn’t a fail-closed guarantee either – it can still leave the CT starting against an empty directory if nothing actually blocks startup on mount failure. Make the remote mount a real dependency of the CT’s own startup path: add a validated systemd drop-in on pve-container@<CTID>.service using RequiresMountsFor= for the mount path, or a tested CT hook script that exits during pre-start when mountpoint -q (or the findmnt check above) fails. Test whichever method you choose against an actual node reboot before relying on it, not just a manual mount/unmount cycle.

Backups, Snapshots, and Restore

Backup design is where a Proxmox LXC bind mount most often produces a nasty surprise, and only during a restore. A host-path bind mount is never included in vzdump, regardless of backup=0 or backup=1 – Proxmox preserves the mount-point config, not the data behind it. Restoring a backup with bind/device mount-point definitions may also need root-level administration; a delegated user can hit an error even with otherwise broad VM/CT permissions.

Mount typeManaged by Proxmox storagevzdump data backupSnapshot/replication
Root filesystemYesYesDepends on backend
Storage-backed mount pointYesYes when backup=1Eligible per backend and mount-point configuration – verify snapshot support and the replicate setting
Host-path bind mountNoNeverExternal to CT snapshot/replication
Device mount pointNoNeverExternal to normal CT lifecycle
Raw lxc.mount.entryNoData not managed by ProxmoxRequires a separate lifecycle plan

A restored CT’s configuration can contain the bind-mount entry correctly – and still not prove the mounted data came back. A clean config restore only means Proxmox reapplied the mount-point definition; the data is expected to already exist independently at that path. Cover each source separately: a local directory via proxmox-backup-client, snapshots, or another file-level tool; an NFS/CIFS share at the NAS/server side; application-native dumps for anything transactional. Test both the CT restore and the external-data reattachment, not just one.

Restore checklist
  1. Restore the CT.
  2. Confirm every bind-mount source actually exists at the expected path – and that it’s the correct source filesystem/data set, not just a path with the right name.
  3. Confirm remote filesystems are genuinely mounted, not represented by an empty directory.
  4. Confirm numeric ownership from both the host and CT views.
  5. Confirm the application process UID/GID inside the restored CT.
  6. Confirm read/write behavior with a disposable test file before trusting it – and confirm nothing already wrote into an empty fallback directory before the external data was reattached.
  7. Restore external data through its own backup method, separately from the CT restore.
  8. Start the application only once the storage dependency is confirmed healthy.

See the PBS restore guide for the mechanics of the CT-level restore itself – this checklist is what to verify once that restore completes.

Migration and Multi-Node Portability

A Proxmox LXC bind mount that works on one node can fail silently on another if the paths aren’t identical. Treat migration with host-path bind mounts as offline unless current Proxmox documentation explicitly supports the exact mode you need – stop the workload, verify the source on every candidate node, and test the target before relying on HA or planned migration. A container that might move needs identical source paths, identical NFS/CIFS mounts with equivalent options, securely reproduced credentials everywhere it could run, and matching UID/GID mapping and Proxmox version on the destination:

findmnt -T /mnt/nfs/media -n -o SOURCE,FSTYPE,TARGET,OPTIONS stat -c '%u:%g %A %n' /mnt/nfs/media

Run this on every candidate node – don’t compare only directory names. The shared=1 mount-point option is easy to misread: it does not mount or replicate the source. It only tells Proxmox that the non-volume path is already available on all nodes – every target node still has to independently expose the same working path and permissions, or the container starts on the new node with a broken or empty mount. The flag is an assertion to Proxmox, not a verification mechanism – Proxmox does not confirm that the path actually contains the same filesystem or data on every node, so two nodes with identically named but different local directories will look correct right up until the container reads the wrong data.

Migration checklist
  1. Use identical source paths on the destination node.
  2. Mount the same NFS/CIFS share with equivalent options.
  3. Reproduce credentials securely, not by copying plaintext files casually.
  4. Verify UID/GID mapping and Proxmox VE version on the destination.
  5. Use shared=1 only when the source is genuinely shared across nodes already.
  6. Test migration with the workload stopped before relying on it operationally.
  7. Remember that marking a path shared does not copy or synchronize any data.

When lxc.mount.entry Is Still Useful

Not every Proxmox LXC bind mount goes through mpX. Raw lxc.mount.entry lines bypass Proxmox’s own mount-point tracking and go straight to LXC’s low-level config – the right tool only for mount options or sources mpX genuinely can’t express, not a starting point.

lxc.mount.entry: /srv/shared data none bind,create=dir,optional 0 0

/srv/shared is the host source. data is relative to the CT root filesystem and becomes /data inside the container. create=dir creates the target directory if it doesn’t exist. optional lets LXC ignore an actual mount-entry failure – it does not verify that a host network mount is genuinely backed by the intended remote filesystem. If the source directory exists locally after the network mount fails, the bind can still succeed and quietly expose the wrong local directory instead of erroring. For critical storage, omitting optional is usually safer: startup should fail rather than proceed quietly with missing data. Proxmox doesn’t track this as an mpX resource, which means none of the GUI-managed lifecycle conveniences apply to it.

Scope note

FUSE filesystems – SSHFS, rclone mounts, mergerfs – deserve a specific caution here rather than a full treatment. Proxmox documentation advises against mounting FUSE filesystems directly inside a CT, because container backup modes may need to freeze the CT and FUSE mounts complicate that. Where possible, mount the FUSE filesystem on the Proxmox host and expose it as a bind mount instead. The host-level FUSE mount still needs its own monitoring and the same fail-closed startup dependency used for NFS/CIFS above – moving the FUSE layer to the host doesn’t make the storage inherently reliable, it just keeps the backup-freeze problem out of the container.

Troubleshooting Workflow

Diagnosing a Proxmox LXC bind mount issue works best in a fixed order. Read the ownership chain in order rather than guessing at the first symptom that looks familiar:

# Container configuration and mount target pct config 200 pct exec 200 -- findmnt /media # Numeric ownership, both sides stat -c '%u:%g %A %n' /mnt/bindmounts/media pct exec 200 -- stat -c '%u:%g %A %n' /media # Application identity inside the CT pct exec 200 -- ps -eo user:20,uid,gid,comm,args pct exec 200 -- id appuser

Comparing ownership tells you what should happen. A disposable test confirms what actually happens – run every step as the real application account, not root, and cover more than file creation:

pct exec 200 -- runuser -u appuser -- sh -c 'printf "bind-mount-test\n" > /media/.bind-mount-test' stat -c '%u:%g %A %s %n' /mnt/bindmounts/media/.bind-mount-test pct exec 200 -- runuser -u appuser -- mv /media/.bind-mount-test /media/.bind-mount-test-renamed pct exec 200 -- runuser -u appuser -- rm /media/.bind-mount-test-renamed

Use a disposable path – don’t test by creating files in a live database or application data directory. This confirms the application can actually write, rename, and delete as itself, that the resulting file lands with the expected host-side UID/GID, and that the problem isn’t limited to a root-only check that masked a real application-level failure.

/proc/1/uid_map inside the CT shows the container’s process user namespace. A Proxmox VE 9.2 per-mount idmap= is a separate mount-ownership translation layered on top of that – so a full picture needs both pct config and the numeric ownership actually seen at the mount point, not just one or the other.

For a CT that fails to start after a mount change:

pct start 200 --debug journalctl -b | grep -Ei 'lxc|apparmor|mount|idmap' dmesg | grep -Ei 'apparmor|denied'

The Proxmox logs guide covers where else to look when the journal output alone doesn’t point at a clear cause.

Verify first, apply the simplest matching fix second, reach for a custom mapping last. Reversing that order is how a five-minute ownership check turns into an afternoon rebuilding a container that won’t start. Avoid a recursive chown -R across a large NAS tree as a first response to a permission mismatch – it fixes one container’s access while quietly breaking every other service, host process, or backup job that depended on the previous ownership.

A privileged CT is not a permissions troubleshooting technique. It changes container root from a remapped unprivileged host identity to a much more trusted host identity, and it weakens the isolation boundary that makes unprivileged the recommended default. It also doesn’t bypass NFS export policy or SMB server ACLs – server-side identity rules still apply regardless of the container’s privilege mode. Changing an existing CT between privileged and unprivileged modes isn’t a normal toggle, either – it generally needs a controlled backup/restore or rebuild process with ownership validation. Use a privileged container only when a workload’s documented requirements justify it and the data source is trusted, not as a shortcut around a permission error.

When to Use a VM Instead

Sometimes the right fix for a stubborn Proxmox LXC bind mount problem is to stop fighting it. If the workload needs kernel modules the host doesn’t provide, a genuinely complex multi-user ACL design, or a filesystem the container’s shared kernel can’t support, that’s the signal to stop tuning UID mappings and move the workload to a VM instead. A VM’s own kernel and storage stack remove the LXC user-namespace translation layer covered in this guide – NFS UID alignment, CIFS mount options, and server-side ACLs can still require configuration, but they’re no longer combined with the container’s host-side UID shift on top. Fighting the container’s shared-kernel model past that point usually costs more time than the VM would have.

Final Recommendation

A bind mount isn’t complicated because the tooling is bad – it’s complicated because a shared-kernel container, a remote filesystem, and a user namespace are three separate ownership models stacked on top of each other, and a permission error can originate from any layer.

For most home lab and small-business deployments, the sweet spot is: mpX by default, remote storage mounted and verified on the host before it ever touches a container with a real fail-closed startup dependency, unprivileged as the default privilege model, and Proxmox VE 9.2’s per-mount idmap= for the specific cases where the default offset doesn’t fit. Bind-mounted data gets its own backup plan, always – vzdump was never backing it up in the first place.

FAQ

Why does my bind mount show nobody:nogroup?

This is the single most common Proxmox LXC bind mount symptom. The source file’s numeric UID/GID can’t be translated through the container’s current user-namespace or mount mapping, so Linux displays the overflow identity, commonly nobody:nogroup. Compare numeric ownership with stat on the host and inside the CT before changing any permissions – and rule out a genuinely-owned UID 65534 or a deliberate NFS squash result first.

Should I use mp0 or lxc.mount.entry?

Use an mpX entry by default. Proxmox tracks the container path and related mount options, though a host-path bind mount still remains outside the Proxmox storage subsystem either way. Use lxc.mount.entry only when you need a low-level LXC mount option mpX genuinely can’t express.

Why can’t my CT write to an NFS share?

Under the default unprivileged host-bind model, verify numeric identity translation before changing anything on the export. With this design, CT root normally maps to a nonzero host UID rather than UID 0, so root_squash often isn’t the cause – but all_squash, anonymous-ID settings, NFSv4 identity mapping, and export ACLs can still be, so evaluate the server’s squash and ACL policy once you know which identity actually reaches it.

Does Proxmox back up LXC bind mounts?

No, and this catches out a lot of setups at the worst possible time. vzdump preserves the bind-mount configuration but never backs up the data behind a host-path bind mount. The backup=1 option applies to storage-backed mount-point volumes, not arbitrary host directories. Back up the source directory or NAS data separately, and expect that restoring the mount-point definition itself may require root-level administration.

Does per-mount idmap work with NFS and CIFS?

Not reliably enough to assume it does for every scenario. The Proxmox VE 9.2 feature depends on kernel ID-mapped-mount support in the underlying filesystem. For NFS and CIFS, numeric-ID alignment or CIFS mount ownership options are the more dependable path – test the exact platform before relying on idmap= for a network share.

Is a privileged CT the easiest fix?

It’s tempting on a stubborn permission problem, but no – it removes the user-namespace translation without bypassing NFS export policy or SMB server ACLs, and converting an existing CT between privileged and unprivileged isn’t a simple toggle either. Treat it as a deliberate workload requirement, not the first response to Permission denied – see the Troubleshooting Workflow section above for why.