Stale file handle is an identity error, not a generic network outage. The NFS client is presenting a server-issued handle for a file, directory or export root, but the server can no longer resolve that handle to the object it currently exposes. A remount often gives the client fresh handles; it does not repair an export whose backing filesystem, fsid, root path or failover identity is still changing.
Recover in that order: confirm ESTALE, decide whether one pathname or the whole export is affected, preserve the mount contract, drain only the processes using it, stabilize the server-side identity, perform a normal unmount/remount, then prove the real application. Avoid making umount -l, umount -f, cache disabling or a fleet-wide reboot the first response.
Linux reports an invalid file handle as ESTALE. The file-handle system-call documentation names deletion as one way a handle becomes stale, while NFS adds server export and filesystem identity to that relationship. By contrast, an unreachable server usually produces retries, server not responding messages or timeouts according to the mount’s hard/soft policy.
Start from the failing client’s mount namespace. Replace /srv/shared with the exact application mountpoint and keep the commands read-only:
date -u
findmnt -T /srv/shared -o TARGET,SOURCE,FSTYPE,OPTIONS
stat /srv/shared
journalctl -k --since '-15 min' | grep -Ei 'nfs|stale|not responding|timed out'
findmnt reads the kernel mount table and reveals the effective source, target, type and options. If stat returns Stale file handle while the server still answers RPC traffic, continue with identity scoping. If logs show only timeouts, solve reachability, routing, firewall, DNS or server availability first; changing export identity during a network incident creates two problems.
The current nfs(5) manual warns that soft and softerr mounts can return errors after retry exhaustion and can cause silent data corruption in some cases. Do not switch a production data mount from hard to soft as an incident shortcut. Mount policy is a workload design decision, not an ESTALE cure.
One failed pathname does not prove that the mount root is invalid. Test a known-good sibling, the mount root and the exact failing object without running a recursive walk that can hang or flood logs.
stat /srv/shared
stat /srv/shared/known-good-directory
stat /srv/shared/path/reported-by-the-application
| Observation | Likely identity boundary | Next useful check |
|---|---|---|
One file or directory returns ESTALE; siblings work |
Object was removed, replaced or renamed in a handle-sensitive path | Ask what changed that pathname on the server |
Mount root and every child return ESTALE |
Export root, backing filesystem or server fsid changed |
Compare client source with current server export |
| Host shell works but one service still fails | Service or container uses another mount namespace or an old open descriptor | Inspect the service process namespace and restart only after state is safe |
| Requests hang and kernel reports server timeouts | Connectivity or server availability, not proven ESTALE |
Restore RPC path before changing mounts |
Object-scoped failure may be legitimate: a deploy replaced a directory tree, a backup restore recreated an inode, or an administrator moved an exported subdirectory. Save unsynced editor or application data to local storage when possible. Recreating a same-named file does not guarantee the old handle becomes valid because the identity is not the pathname alone.
Capture enough evidence to reconstruct the exact mount. A casual mount server:/export /srv/shared can silently negotiate a different NFS version, security flavor or option set than the application used before the incident.
findmnt -T /srv/shared -o TARGET,SOURCE,FSTYPE,OPTIONS -n
grep -nF '/srv/shared' /etc/fstab
systemctl list-units --type=mount --all | grep -F 'srv-shared'
Record the source hostname or address, export path, NFS version, security flavor, hard or soft behavior, automounter or systemd ownership, and whether containers bind-mount the path. This contract remains client-side regardless of hosting provider; a reboot cannot identify which server-side object identity changed.
Also preserve application evidence: failing operation, UTC timestamp, affected path, recent deployment/restore/failover, and whether pending writes exist. A clean remount can erase the easiest symptom while leaving the cause ready to recur.
A filesystem is busy when a process holds an open file, working directory or another reference. Identify those owners instead of killing every process that appears near the mount.
sudo fuser -vmM /srv/shared
sudo lsof +f -- /srv/shared
fuser -M requires the supplied path to be a mountpoint, which is a useful guard against targeting an ordinary directory by mistake. lsof can itself block on an unhealthy network filesystem, so use a timeout policy from a second administration session and rely on service ownership when the walk is unsafe.
Stop or quiesce the named application through its normal service, container or orchestration path. Preserve queues and unfinished transactions first. Move every operator shell outside the mount and then attempt the least surprising action:
cd /
sudo umount /srv/shared
findmnt -T /srv/shared
The util-linux umount(8) manual limits forced unmount to cases such as unreachable NFS and notes that it still may hang. Its lazy option immediately detaches the mount from the hierarchy, cleans references later, and warns that network shares may not be remountable afterward; a reboot is normally expected. Therefore umount -l is containment for a stuck, unreachable share—not routine repair for a reachable server returning ESTALE.
If normal unmount stays busy, return to process and namespace ownership. Do not stack a fresh mount over the same directory merely to make ls look healthy; hidden old mounts and processes can continue using different views.
Containers, system services with namespace isolation and manual unshare sessions may not see the same mount table as the host shell. A successful host remount is insufficient when the application process still points at its original namespace or inherited descriptor.
Capture the application’s PID and inspect from its namespace without changing it:
app_pid=APP_PID
sudo nsenter -t "$app_pid" -m findmnt -T /srv/shared -o TARGET,SOURCE,FSTYPE,OPTIONS
sudo readlink "/proc/$app_pid/ns/mnt"
sudo readlink /proc/1/ns/mnt
Replace APP_PID with a numeric process ID before running the block. Different namespace identifiers prove different mount views; they do not authorize an arbitrary restart. Decide whether the service must be recreated, whether a container bind mount should be refreshed, or whether the orchestrator owns the mount lifecycle. Restart only the smallest workload boundary that can safely release the stale view.
Client recovery lasts only when the server resolves handles consistently. On the NFS server, compare the exported path with the filesystem actually mounted beneath it and with the export table presented to clients.
findmnt -T /srv/nfs/shared -o TARGET,SOURCE,FSTYPE,OPTIONS
stat -c 'device=%d inode=%i path=%n' /srv/nfs/shared
sudo exportfs -v
sudo grep -Rns -- '/srv/nfs/shared' /etc/exports /etc/exports.d
Replace the server path with the real export root. Run exportfs -ra only after reviewing and validating the intended export configuration; it applies the table described by exports(5), so a typo can affect every client.
| Server-side change | Why old handles fail | Safe repair boundary |
|---|---|---|
| File or directory was deleted and recreated | New object has a different identity even at the same pathname | Recover unsaved data if possible, then reopen that object from a fresh lookup |
| Export root now sits on another filesystem or restored volume | Existing handles encode the previous filesystem/object identity | Stabilize the intended backing mount before re-export and client remount |
Cluster failover exposes inconsistent fsid or export topology |
Another node cannot resolve handles issued by its peer | Make export identity consistent across nodes, then schedule client refresh |
subtree_check export sees rename-heavy paths |
File-handle location data can make renames unreliable | Review whether exporting the filesystem root or no_subtree_check fits the security model |
| File-handle signing key changed while mounts stayed active | Previously signed handles no longer validate | Preserve key continuity or coordinate a complete client remount window |
exports(5) explains that subtree checking places path-location information in file handles and can cause trouble when open files are renamed; current nfs-utils defaults to no_subtree_check. That default is not permission to weaken an existing security design blindly. Review export boundaries, client authorization and rename behavior together.
A central export serving many clients may benefit from clearer resource and failure ownership, but changing hardware does not create stable fsid values or a safe failover contract automatically. If the backing mount is an unhealthy LVM thin volume, complete the thin-pool recovery workflow before asking NFS clients to trust it again.
Once server identity is stable and the old client mount is normally detached, mount through the recorded owner. Prefer systemctl start for a systemd mount unit, the automounter for autofs, or the exact /etc/fstab entry rather than inventing an ad hoc command.
sudo mount /srv/shared
findmnt -T /srv/shared -o TARGET,SOURCE,FSTYPE,OPTIONS
stat /srv/shared
Do not declare recovery from a successful ls. Use an application-approved test directory and prove each operation the workload depends on. The following example creates and removes only its uniquely named probe; set MOUNT first and confirm that the directory permits a disposable test file.
MOUNT=/srv/shared/approved-probe-directory
probe="$MOUNT/.nfs-probe-$(hostname)-$(date +%s)"
printf 'nfs recovery probe\n' > "$probe"
stat "$probe"
cat "$probe"
rm -- "$probe"
Add a lock test when the application coordinates writers through NFS locking. Verify rename, ownership, permissions, ACLs, extended attributes and close-to-open visibility when the workload uses them. For Filestash, prove upload and download through the application after the mount test; the secure deployment workflow provides that higher-layer context. Other workloads need their own representative transaction from outside the host, such as a media fetch, backup write, artifact publish or database-dump handoff.
Recovery is complete when mount identity stays stable, the intended application succeeds, no new ESTALE appears, and a controlled service restart returns to the same export. A green mount command alone proves only that one lookup worked.
Future prevention belongs in the storage change plan. Preserve the exported filesystem and fsid across failover when the architecture supports it. When a restore or migration must replace identity, drain writers, record client mounts, switch the server once, refresh every affected client namespace, and keep a rollback path that does not expose two writable copies.
Ownership must also be explicit. Document where provider responsibility ends and guest filesystem or export ownership begins; the managed-versus-unmanaged responsibility guide can help define that boundary. An NFS incident can cross both sides, so the change record needs one accountable owner on each.
Availability is not retention. NFS can centralize files yet still propagate deletion, corruption or compromised credentials. Where the export stores recovery copies, pair it with versioning outside the same failure domain and evaluate immutable object-lock backup design rather than treating a mounted writable share as the final backup boundary.
Monitor for ESTALE in application and kernel logs, but alert on rate and workload impact instead of every isolated line forever. More importantly, record export root, backing filesystem identity, fsid policy, failover node consistency, client namespace owners and the exact acceptance transaction. The prevention artifact is a tested identity contract, not a cache-tuning value.
One file can return ESTALE when that server object was deleted, replaced or renamed while the client retained its old handle. Sibling objects and the export root can remain valid because their handles still resolve.
No. Cache timing can change when attributes are revalidated, but it cannot make an invalid server-issued handle identify a replacement object. Reopen the object or remount after the server export identity is stable.
umount -l be the first NFS stale-handle repair?Lazy unmount should not be the first repair. It detaches the mount immediately and cleans references later; current util-linux guidance warns that a network share may not be remountable afterward and normally expects a later reboot. Drain consumers and try normal unmount first.
umount -f appropriate for NFS?Forced unmount is mainly a recovery option for an unreachable NFS server after application state and data-integrity risks are accepted. A reachable server returning ESTALE needs export-identity diagnosis, not automatic force.
fsid break mounted clients?Yes. File handles identify the exported filesystem and object, so inconsistent fsid or backing-filesystem identity across re-export or failover can invalidate handles already held by clients.
Completion requires a stable remounted source and option set, successful application reads and writes, required metadata or lock behavior, no recurring ESTALE, and a controlled service restart that returns to the same export.