It’s 02:13. A VM backup starts, then immediately faceplants. A container won’t start. Proxmox suddenly thinks your NFS datastore is haunted: stale file handle. You reboot something, it “fixes” itself, and everyone learns the wrong lesson.
Stale file handles aren’t random. They’re a very specific class of “the server doesn’t recognize what you’re pointing at anymore.” Once you understand what an NFS file handle is, you can stop treating this like weather and start treating it like a preventable production defect.
What “stale file handle” actually means (in Proxmox terms)
Proxmox is not special here; it’s “just Linux.” When Proxmox mounts an NFS storage, it’s relying on the Linux NFS client to map paths (like /mnt/pve/nfs-prod) to server-side filesystem objects. The NFS client caches a small opaque identifier for each file/directory it touches: the file handle.
That handle is issued by the NFS server. It encodes “this object, on this filesystem, in this server’s view of the world.” The handle is designed to survive normal operations like reboots and network hiccups. But it does not survive certain server-side events: exports moving, filesystems being replaced, inode tables being rebuilt, snapshots being promoted, or the server being “helped” by someone with root access and optimism.
When Proxmox does something mundane—open a qcow2, list a directory, lock a VM disk—and the server replies “I don’t know that handle anymore,” the client reports ESTALE. Proxmox surfaces it as “stale file handle” and then cascades into failures: VM start errors, backup failures, migration failures, or storage marked offline.
Important nuance: a stale file handle is not “NFS is down.” It’s “NFS is up, but the object identity changed.” That difference matters for both diagnosis and prevention.
Here’s the reliability framing I wish everyone used: stale file handle is an identity consistency problem, not a connectivity problem.
One quote that belongs on every NFS incident channel (paraphrased idea): John Allspaw’s idea: the conditions for failure are built into the system long before the incident.
Stale handles are exactly that—latent conditions plus one trigger.
Short joke #1: NFS stands for “No, File’s Somewhere”… right up until it stands for “Now File’s Stale.”
Facts and context: why this keeps biting people
Some history and “why” helps because NFS has quirks that are not obvious if you grew up on local disks, object storage, or distributed filesystems designed this century.
- NFS was designed for stateless servers (especially v2/v3). That statelessness pushed complexity into clients: caching, retries, and weird edge cases like stale handles.
- File handles are opaque by design. The server can change their internal structure across versions or configuration changes; the client must treat them as “magic cookies.”
- NFSv3 commonly ties identity to filesystem/inode details. Replace the filesystem or reshuffle inodes and old handles become meaningless.
- NFSv4 introduced a “pseudo filesystem” and a different mount model. It improved some things, but also added new foot-guns around export paths, referrals, and idmapping.
- Some NAS appliances virtualize filesystems under the hood. When they fail over, upgrade, or rebalance, the backing identity can change even if the export path string stays the same.
- Hard mounts are the Linux default for a reason. A “soft” mount can turn transient server pain into silent data corruption, which is far worse than a stuck process.
- “Stale file handle” is older than your virtualization stack. You can find it in UNIX-era lore; modern hypervisors just make the blast radius larger.
- Locking semantics have a long and messy history. NLM for v3 and integrated locking for v4 can interact with failovers and re-exports in ways that look like “random” VM disk issues.
Takeaway: NFS can be reliable, but only if you treat file identity as part of your storage contract. If your NFS server can silently swap the backing filesystem, you don’t have a contract—you have vibes.
Root causes that produce stale file handles
1) The export now points at a different filesystem
This is the classic. The export path string is unchanged, but the underlying filesystem changed: new ZFS dataset mounted there, new ext4 volume, a replicated filesystem promoted, or a different NAS volume mounted into the same directory.
NFS file handles typically include a filesystem identifier. If that identifier changes, old handles become stale. This often happens after “storage maintenance” where someone unmounts and remounts the export path, or after failover when the standby node’s export is not byte-for-byte identical in identity metadata.
2) Inode reuse or inode table regeneration (less common, but real)
Some filesystems and some recovery operations can result in different inode identity for “the same path.” If the server decides the object at that path is now a different inode, handles that referenced the old inode are stale. You’ll see this with filesystem rebuilds, aggressive snapshot rollbacks, and certain “restore from backup into same path” workflows.
3) Export options or NFS server configuration changed mid-flight
Changing exports and reloading the server can invalidate the server’s idea of what was exported and with which filesystem ID. In NFSv3, fsid matters more than most people realize. In NFSv4, the pseudo-root and export tree matter.
4) NAS failover where the client talks to “the same IP” but a different server personality
Highly available NFS often uses a floating IP. Great. But if failover switches to a node that does not preserve filesystem identity exactly (or does it after a delay), clients can keep old handles and then explode. Some appliances have “grace periods” or handle remapping; some don’t. Some do it until you enable a feature that disables it. Ask me how I know.
5) Snapshot rollback / clone promotion on the server
Rollback is seductive: “we’ll just roll the dataset back.” If the rollback changes inode identity or underlying filesystem generation, handles go stale. VM disk images are particularly sensitive because they’re long-lived and actively open.
6) Proxmox node behavior: cached directory entries and busy processes
Even if the server is now “correct,” clients can keep stale references if processes have open file descriptors, current working directories, or cached dentries pointing at old handles. That’s why “umount and remount” sometimes fixes it—and sometimes fails with “device is busy,” which is Linux politely telling you a process is camping there.
7) “Optimization” mount options that change semantics
Tuning NFS for performance is fine. Tuning it for vibes is not. Options like actimeo, lookupcache, and aggressive attribute caching can magnify the window where clients operate on outdated identity assumptions. Usually you won’t get stale handles directly from caching, but you will get higher rates of weirdness around rename/unlink and rapid rollbacks.
Short joke #2: The fastest way to generate stale file handles is to say “don’t worry, it’s just NFS” out loud. NFS hears you.
Fast diagnosis playbook (check first/second/third)
The goal is to answer three questions quickly:
- Is this an identity problem (ESTALE) or a connectivity/performance problem (timeouts)?
- Is the failure isolated to one Proxmox node or cluster-wide?
- Did the server change what it’s exporting, or did the client cache something broken?
First: confirm the error and scope
- Check Proxmox task logs for
ESTALE/ stale file handle. - On multiple nodes, try listing the same path. If only one node sees stale, it’s usually client cache/process state. If all nodes see stale, the server/export changed.
- Look at kernel logs on the client for NFS messages. They often include the server IP and the mountpoint.
Second: verify the mount is what you think it is
- Check
findmntto confirm NFS version, server, export path, and mount options. - Check
/proc/fs/nfsfs/volumesto see NFS client’s view of volumes and their IDs. - On the server, confirm exports didn’t change and that the filesystem behind the export is the same dataset/volume.
Third: decide whether to fix on client, server, or both
- If the server export points somewhere new: fix server/export identity first, then remount clients.
- If the server is stable but one node is broken: kill the processes holding stale fds, then remount.
- If HA failover triggered it: you need to fix failover identity preservation, not just remount. Remount is a bandage.
Practical tasks: commands, expected output, and decisions
Below are real, runnable commands you can use on Proxmox nodes and typical Linux NFS servers. Each task includes what the output means and what decision to make next.
Task 1: Confirm the mount and NFS version
cr0x@pve1:~$ findmnt -t nfs,nfs4 /mnt/pve/nfs-prod
TARGET SOURCE FSTYPE OPTIONS
/mnt/pve/nfs-prod nfs01:/exports/prod nfs4 rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,proto=tcp
Meaning: You’re mounted to nfs01:/exports/prod using NFSv4.1 with a hard mount.
Decision: If the SOURCE is not what you expect (wrong host/export), stop. Fix Proxmox storage definition or DNS before chasing stale handles.
Task 2: Reproduce the stale error in a minimal way
cr0x@pve1:~$ ls -la /mnt/pve/nfs-prod/images
ls: cannot access '/mnt/pve/nfs-prod/images': Stale file handle
Meaning: This is a true ESTALE symptom on directory lookup.
Decision: Check whether other nodes see the same. If yes, suspect server-side export/filesystem identity change.
Task 3: Check kernel messages for NFS client complaints
cr0x@pve1:~$ dmesg -T | tail -n 20
[Thu Dec 26 01:58:41 2025] NFS: stale file handle
[Thu Dec 26 01:58:41 2025] NFS: server nfs01 not responding, still trying
[Thu Dec 26 01:58:57 2025] NFS: server nfs01 OK
Meaning: You may have both identity issues (stale handle) and brief server unresponsiveness. They can co-occur during failover/restart.
Decision: If “not responding” repeats, also investigate network/server load. But don’t ignore the stale handle: it won’t heal by waiting.
Task 4: Identify who is “camping” in the mount (blocks unmount)
cr0x@pve1:~$ fuser -vm /mnt/pve/nfs-prod
USER PID ACCESS COMMAND
/mnt/pve/nfs-prod: root 21940 ..c.. pvedaemon
root 31211 ..c.. pve-backup
root 1402 ..c.. systemd
Meaning: Those PIDs have current directory or open files under the mount.
Decision: If you need to remount, stop the relevant Proxmox services/tasks cleanly first, or you’ll be doing the “lazy unmount” dance.
Task 5: See NFS client’s internal volume list (useful for “what is mounted really?”)
cr0x@pve1:~$ cat /proc/fs/nfsfs/volumes
NV SERVER PORT DEV FSID FSC
v4 nfs01 2049 0:50 0:0 yes
Meaning: The client sees an NFSv4 volume from nfs01. FSID here is not as descriptive as v3, but it confirms the client’s view.
Decision: If you expected multiple mounts or different servers and you only see one, you may be mounting via an HA VIP and not noticing failovers.
Task 6: Check Proxmox storage config for the NFS entry
cr0x@pve1:~$ cat /etc/pve/storage.cfg
nfs: nfs-prod
server nfs01
export /exports/prod
path /mnt/pve/nfs-prod
content images,iso,vztmpl,backup
options vers=4.1,proto=tcp,hard,timeo=600,retrans=2
Meaning: Proxmox is configured to mount that export with specific options.
Decision: If you’re missing explicit vers and the environment mixes servers, pin versions intentionally. Accidental v3/v4 differences are a recurring source of pain.
Task 7: Validate exports from the client side (NFSv3 view; still useful)
cr0x@pve1:~$ showmount -e nfs01
Export list for nfs01:
/exports/prod 10.10.20.0/24
/exports/dev 10.10.20.0/24
Meaning: The server advertises those exports. On NFSv4 this may not tell the whole story (pseudo-root), but it catches basic drift.
Decision: If the export disappeared or permissions changed, fix that first. A stale handle sometimes follows an export reconfiguration.
Task 8: On the NFS server, confirm the export config and fsid
cr0x@nfs01:~$ sudo exportfs -v
/exports/prod 10.10.20.0/24(rw,sync,wdelay,hide,no_subtree_check,sec=sys,fsid=100)
/exports/dev 10.10.20.0/24(rw,sync,wdelay,hide,no_subtree_check,sec=sys,fsid=101)
Meaning: The server is exporting with explicit fsid values. That’s good hygiene for stability, especially with NFSv3 and some HA setups.
Decision: If fsid is missing and you’re doing anything clever (bind mounts, ZFS datasets, failover), add explicit fsid and test. If fsid changed recently, expect stale handles until clients remount.
Task 9: Confirm the underlying filesystem behind the export didn’t change
cr0x@nfs01:~$ mount | grep ' /exports/prod '
tank/prod on /exports/prod type zfs (rw,xattr,noacl)
Meaning: Export path maps to a ZFS dataset tank/prod.
Decision: Compare with your known-good baseline. If someone replaced it (e.g., now it’s tank/prod-new), that’s your stale handle trigger.
Task 10: Detect “the directory got replaced” (inode number changes across time)
cr0x@nfs01:~$ stat -c '%n inode=%i dev=%d' /exports/prod /exports/prod/images
/exports/prod inode=48 dev=46
/exports/prod/images inode=1024 dev=46
Meaning: You’re collecting identifiers that help catch “we remounted something else here” incidents. If dev changes, the mount changed.
Decision: If dev/inode changed compared to earlier records, treat this as a server-side identity change and plan a coordinated client remount (and fix the workflow that caused it).
Task 11: Try a clean remount on a Proxmox node (after stopping dependent tasks)
cr0x@pve1:~$ sudo systemctl stop pvedaemon pveproxy
cr0x@pve1:~$ sudo umount /mnt/pve/nfs-prod
umount: /mnt/pve/nfs-prod: target is busy.
Meaning: Something still holds it busy (often backup, qemu, or a shell with cwd inside).
Decision: Use fuser/lsof to identify and stop the specific processes. Don’t jump straight to lazy unmount unless you understand the implications.
Task 12: Find open files under the mount (more precise than fuser)
cr0x@pve1:~$ sudo lsof +f -- /mnt/pve/nfs-prod | head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
pve-backup 31211 root cwd DIR 0,50 4096 2 /mnt/pve/nfs-prod/backup
qemu-system 9982 root 27u REG 0,50 2147483648 7 /mnt/pve/nfs-prod/images/101/vm-101-disk-0.qcow2
Meaning: A VM and backup process have open handles. If those handles are stale, they’ll keep erroring until restarted and the mount is refreshed.
Decision: Stop/migrate the VM(s) that run from this storage before remounting. Otherwise you’re betting your uptime on undefined behavior.
Task 13: Use a lazy unmount only as a controlled last resort
cr0x@pve1:~$ sudo umount -l /mnt/pve/nfs-prod
cr0x@pve1:~$ sudo mount /mnt/pve/nfs-prod
cr0x@pve1:~$ ls /mnt/pve/nfs-prod
backup images iso vztmpl
Meaning: The mount is back and directory listing works. Lazy unmount detached the mount from the namespace while old references drain.
Decision: Immediately verify running qemu processes aren’t still referencing the old mount. If they are, restart them cleanly. Lazy unmount is not a free lunch.
Task 14: Confirm Proxmox sees the storage as available
cr0x@pve1:~$ pvesm status
Name Type Status Total Used Available %
local dir active 19660800 8214528 11446272 41.79%
nfs-prod nfs active 104857600 20971520 83886080 20.00%
Meaning: Storage is active from Proxmox’s perspective.
Decision: If it’s still “inactive” but Linux mount works, check permissions, content types, and Proxmox services. If Linux mount is broken, don’t blame Proxmox.
Task 15: If you suspect failover, confirm which server IP you’re actually talking to
cr0x@pve1:~$ rpcinfo -t nfs01 nfs 4
program 100003 version 4 ready and waiting
Meaning: RPC connectivity exists to the resolved nfs01 target. In an HA VIP setup, this doesn’t prove which physical node is active, but it confirms service availability.
Decision: If HA is involved, verify identity preservation on failover. Stale handles that cluster-wide coincide with VIP failover are a design issue.
Task 16: Server-side sanity check: did someone “reload exports” recently?
cr0x@nfs01:~$ sudo journalctl -u nfs-server -u nfs-mountd --since "2 hours ago" | tail -n 30
Dec 26 01:54:02 nfs01 exportfs[18842]: exporting 10.10.20.0/24:/exports/prod
Dec 26 01:54:02 nfs01 systemd[1]: Reloaded NFS server and services.
Meaning: Exports were reloaded in the incident window. That’s not automatically bad, but it’s a strong correlation lead.
Decision: If reload coincides with stale handles, review what changed (exports, mountpoints, fsid, bind mounts). Put “export changes require change control” on the policy list.
Common mistakes: symptom → root cause → fix
1) VM disks intermittently fail to start after NAS maintenance
Symptom: qm start fails with I/O errors; Proxmox logs show stale file handle on VM disk path.
Root cause: Export path stayed the same, but the NAS swapped/rolled back the underlying volume or changed filesystem identity during maintenance/failover.
Fix: Make exports stable: explicit fsid (where applicable), consistent filesystem identity on HA nodes, avoid “swap what’s mounted under the export path.” After the server is corrected, remount clients and restart affected qemu processes.
2) Only one Proxmox node sees stale handles; others are fine
Symptom: Storage is “active” on node A but directory listings throw stale handle; node B can browse normally.
Root cause: Node A has processes holding stale file descriptors or cached dentries; node B remounted or never touched the changed objects.
Fix: Identify processes with lsof/fuser, stop/migrate workloads using the mount, then cleanly remount on the affected node.
3) Backups fail with stale handle right after “restore into place”
Symptom: Backup job dies while scanning directories; errors point at a folder that was recently restored.
Root cause: Restore workflow replaced directories/files in a way that changed inode identity while clients still cached handles to old objects.
Fix: Don’t restore by swapping whole trees under an active export. Restore into a new path, then do a controlled cutover (and remount clients if you must replace the tree).
4) Someone “fixed” it with soft mounts and now you have silent corruption risk
Symptom: Stale handle errors “go away,” but you see random application errors and truncated files later.
Root cause: soft can cause NFS operations to fail early; many applications aren’t built to handle that safely for VM images or databases.
Fix: Use hard mounts for VM storage. Address the underlying identity/failover problem. If you need bounded failure, use correct timeouts and monitoring, not soft.
5) Stale handle after changing export options (especially subtree/bind mount games)
Symptom: After “cleanup,” some directories throw stale file handle while others work.
Root cause: Export tree changed; bind mounts or subdirectories were exported differently; fsid assignment changed.
Fix: Keep a stable export layout. Prefer exporting a dedicated filesystem/dataset per Proxmox storage. Avoid exporting deep subdirectories with moving parents.
6) “We use an HA VIP, so it’s fine” (it isn’t, by default)
Symptom: Cluster-wide stale handles during failover tests; everything returns after remount/reboot.
Root cause: The standby node doesn’t preserve file handle identity or presents a different filesystem ID behind the same export.
Fix: Fix HA NFS properly: shared backing store with consistent identity, or an HA NFS solution that guarantees stable file handles across failover. Test with live workloads, not just ls.
Three corporate mini-stories from the trenches
Mini-story 1: The incident caused by a wrong assumption
They had a tidy Proxmox cluster and a tidy NAS. The export path was /exports/prod and it had been that way for years. During a storage refresh, someone created a new volume and mounted it on /exports/prod during a maintenance window. Same directory name, same permissions, same IP. They assumed “same path” meant “same storage.”
It worked for a bit. Fresh VM migrations landed on the new volume and ran. The next day, backups started failing, then a couple of VMs rebooted for unrelated patching and wouldn’t come back. Stale file handle everywhere. The on-call team treated it like an NFS outage and did the traditional rituals: restart services, then reboot a Proxmox node, then reboot the NAS controller. The error changed shape but didn’t go away.
The turning point was comparing the server-side mount source and the ZFS dataset name behind the export. It was new. The old volume was still there, mounted elsewhere. Clients had cached handles to objects on the old filesystem; the export now pointed at the new one. The NFS server wasn’t “down,” it was politely refusing to acknowledge a past life.
They fixed it by doing the boring work: create a new export path for the new volume, add it as a new Proxmox storage, migrate disks explicitly, then decommission the old one. The postmortem action item was blunt: “Stop replacing the filesystem under an existing export path.” Everyone hated it until the next refresh, when nobody got paged.
Mini-story 2: The optimization that backfired
A different shop had performance complaints: backups were slow, VM disk I/O had spikes, and someone declared the problem was “NFS metadata chatter.” They tuned mount options aggressively—attribute caching, lookup cache behavior, larger rsize/wsize, reduced retrans, and a few options copy-pasted from a blog post written for a different workload.
Performance improved in the happy path. Then they performed a planned failover test on their HA NAS. The failover itself was clean, but Proxmox nodes started reporting stale handles and weird directory listing inconsistencies. Only some nodes. Only some subdirectories. It looked like a cosmic ray incident.
The real issue: the tuning increased the window where clients believed their cached view was correct, while the server-side export tree was briefly in a transitional state during failover. The clients weren’t wrong to cache; they were wrong to cache for that long given the server behavior. And because the “optimization” was rolled out gradually, different nodes had different behaviors. Good luck debugging that at 03:00.
They rolled back to a conservative baseline and then fixed the server-side HA sequencing so the export became available only when the backing filesystem was fully consistent. The lesson: if you’re going to tune, tune against a failure model. Otherwise you’re just making the failure more interesting.
Mini-story 3: The boring but correct practice that saved the day
One enterprise team treated NFS exports like API contracts. Each Proxmox storage had its own dedicated filesystem/dataset. Exports were declared with explicit identifiers, changes were reviewed, and “swap what’s mounted here” was simply not allowed. The policy was unpopular because it removed a class of “quick fixes.” That was the point.
They still had incidents—network blips, NIC firmware bugs, a switch that decided to drop packets like it was cleansing its aura. But stale file handles were rare, and when they occurred, the blast radius was small. One export, one dataset, one storage ID. Diagnosis was fast because there was less ambiguity.
Then a server patch rebooted the NFS node at a bad time. Clients stalled (hard mount doing its job), monitoring lit up, and the on-call followed the runbook: confirm NFS is back, validate export identity, remount only if necessary, restart only the impacted jobs. No node reboots. No random “try again.” The incident was short, boring, and not a career event.
That’s the highest compliment in ops: the incident behaved exactly like the runbook said it would.
Prevention: what to standardize and what to ban
Standardize: stable exports that don’t move
If you want fewer stale handles, stop doing the thing that creates them: changing the filesystem identity behind an export while clients are mounted.
- One Proxmox storage ↔ one server-side filesystem/dataset. Avoid exporting deep subdirectories of a shared volume for unrelated purposes. It increases the chance someone “cleans up” the parent.
- Never replace what is mounted under an export path. Create a new export path, cut over explicitly, then retire the old path.
- Use explicit export identifiers where appropriate. On many Linux NFS servers, setting
fsidon exports is a stability win, especially in NFSv3 and in multi-export scenarios. - Pin NFS versions intentionally. Mixed v3/v4 behaviors across nodes are a breeding ground for inconsistent failure modes.
Standardize: conservative mount options for VM storage
For VM images, your priorities are correctness and predictable failure behavior, not benchmark wins.
- Use
hardmounts. If the server stalls, your I/O stalls. That’s honest. It lets you fail over, fix, or fence without corrupting disks. - Use TCP. Yes, UDP exists historically. No, you don’t want it for VM disk workloads in 2025.
- Use sensible timeouts. A common pattern is a longer
timeowith limitedretransand good alerting, so you detect “stuck” behavior without turning it into silent failure. - Keep attribute caching sane. Don’t go wild unless you can reproduce failure tests under the tuned settings.
Ban: “roll back the dataset that hosts running VM disks”
If your NFS server hosts active VM disks and you roll back snapshots under them, you’re playing filesystem roulette. Even if the server survives, clients can’t reconcile “the past” with cached handles. Instead:
- Restore into a new dataset/path.
- Verify integrity.
- Schedule controlled migration/cutover.
Ban: exporting paths that depend on bind mounts without change control
Bind mounts are handy. They’re also an excellent way to change filesystem identity invisibly. If you must use them, treat bind mount changes like production changes with a maintenance window, client coordination, and a rollback plan.
Design for HA: stable identity across failover or don’t pretend it’s HA
HA NFS is hard because “the same IP” is not “the same filesystem identity.” If failover switches to a different backend that can’t preserve handles, you’ll see stale handles cluster-wide. Solutions include:
- A shared backend filesystem with consistent identity and correct NFS HA support.
- Failover orchestration that ensures exports appear only after the filesystem is mounted consistently and ready.
- Avoiding NFS for VM disks entirely if your HA story can’t guarantee identity (use block storage or a clustered filesystem designed for it).
Checklists / step-by-step plan
Step-by-step: when stale file handle hits production
- Confirm scope: one node vs all nodes. Run
lson the same path from two nodes. - Capture evidence before “fixing”: kernel logs (
dmesg), Proxmox task logs,findmntoutput. - Identify impacted workloads: which VMs/CTs use that storage. Plan a pause/migration if needed.
- Check server export identity: confirm the export points to the expected filesystem/dataset; check for recent export reloads and mount changes.
- Fix server-side drift first: if export moved, put it back or create a new export and reconfigure Proxmox.
- Stop processes holding stale fds on the client:
lsof/fuser, then stop or migrate VMs using the mount. - Remount cleanly: unmount, mount, verify directory listing, verify file access.
- Restart only what needs restarting: qemu processes for affected VMs, backup jobs, etc.
- Post-incident: identify the server-side trigger and write the policy that prevents it from recurring.
Checklist: “export stability” requirements for Proxmox NFS datastores
- Dedicated filesystem/dataset per datastore
- No “swap mount under path” allowed
- Explicit export IDs (where applicable)
- Change control for export edits and reloads
- Documented mount options pinned in Proxmox storage.cfg
- HA failover tested with live open files, not just directory listings
Checklist: “before maintenance” on NFS server hosting Proxmox
- Confirm which Proxmox storages are backed by which exports
- Quiesce or migrate high-risk workloads (heavy write VMs, backups)
- If failover/upgrade changes export identity, schedule client remount window
- Communicate expected behavior: hard mounts may stall during reboot
- After maintenance: verify exports, mountpoints, and dataset identity before declaring green
FAQ
1) Is “stale file handle” a Proxmox bug?
No. Proxmox is surfacing a Linux NFS client error (ESTALE). The usual trigger is server-side identity change or HA failover behavior.
2) Why does rebooting a Proxmox node sometimes “fix” it?
A reboot drops cached state and open file descriptors, forcing fresh handles after remount. It’s a blunt instrument that hides the real cause and costs you more downtime than necessary.
3) Should I use NFSv3 or NFSv4.x for Proxmox?
Either can work, but pick deliberately and standardize. NFSv4.x simplifies some aspects (single port, integrated locking), while v3 has simpler semantics in some environments. Mixing versions across nodes is asking for inconsistent behavior.
4) Are “soft” mounts a good way to avoid stuck VMs?
No for VM disks. Soft mounts can cause operations to fail mid-write in ways applications don’t handle safely. Hard mounts plus good monitoring is the grown-up option.
5) Can stale file handle happen even if the server never rebooted?
Yes. Any change that effectively replaces the filesystem object identity—snapshot rollback, dataset remount, bind mount switch, export reconfiguration—can do it.
6) Why does it sometimes affect only one directory under the mount?
Because handles are per object. If only one subtree was replaced (restored, rolled back, remounted via bind mount), only handles referencing that subtree go stale.
7) What’s the safest remediation when VM disks are on the affected NFS?
Stop or migrate VMs using that storage, remount the datastore, then restart the VMs. If you can’t stop them, you’re gambling with data integrity and recovery time.
8) Does explicit fsid always prevent stale handles?
No. It reduces a class of problems (especially around export identification and changes) but won’t save you from replacing the underlying filesystem/dataset or doing destructive rollbacks.
9) How do I tell identity problems from simple latency/timeouts?
Latency/timeouts show up as “server not responding” and hung I/O; stale handle shows up as immediate Stale file handle errors on lookup/open. They can occur together during failover.
10) If I must do server-side rollback, what’s the least bad option?
Rollback into a new path/dataset and cut over by changing Proxmox storage to the new export (and remounting). Don’t rollback in-place under active clients.
Practical next steps
If you want fewer stale file handle incidents, do these in order:
- Audit export stability: confirm that each Proxmox NFS datastore maps to a dedicated server-side filesystem/dataset that is never replaced in-place.
- Standardize mounts: pin NFS version and options in
/etc/pve/storage.cfg. Remove ad-hoc node differences. - Fix HA honestly: either guarantee stable identity across failover or stop pretending the VIP makes it safe.
- Write the runbook: the fast diagnosis checks, the “who is holding the mount” steps, and the controlled remount procedure.
- Change the culture: “just remount it” is not a solution; it’s a symptom of missing contracts between storage and compute.
Stale file handles are the system telling you the truth: something changed underneath you. Make those changes explicit, controlled, and testable—and the truth becomes a lot less dramatic.