kubernetes/kubernetes · critical
unable to acquire file lock on %q: %w
Error message
unable to acquire file lock on %q: %w
What it means
From run() (server.go:701-702): flock.Acquire failed on --lock-file-path. The lock file enforces that only one kubelet runs per node (and supports --exit-on-lock-contention for self-termination on contention). Acquisition fails when the file cannot be created/opened or an existing holder won't release within the retry window.
Source
Thrown at cmd/kubelet/app/server.go:702
kernelVersion, err := utilkernel.GetVersion()
if err != nil {
logger.Error(err, "Failed to detect kernel version for MemoryQoS compatibility check")
} else if kernelVersion.LessThan(utilversion.MustParseGeneric(utilkernel.MemoryQoSMinKernelVersion)) {
logger.Info("Warning: MemoryQoS memory.high throttling may cause process livelock on older kernels",
"currentKernel", kernelVersion,
"minimumKernel", utilkernel.MemoryQoSMinKernelVersion)
}
}
}
// Obtain Kubelet Lock File
if s.ExitOnLockContention && s.LockFilePath == "" {
return errors.New("cannot exit on lock file contention: no lock file specified")
}
done := make(chan struct{})
if s.LockFilePath != "" {
logger.Info("Acquiring file lock", "path", s.LockFilePath)
if err := flock.Acquire(s.LockFilePath); err != nil {
return fmt.Errorf("unable to acquire file lock on %q: %w", s.LockFilePath, err)
}
if s.ExitOnLockContention {
logger.Info("Watching for inotify events", "path", s.LockFilePath)
if err := watchForLockfileContention(ctx, s.LockFilePath, done); err != nil {
return err
}
}
}
if len(s.ShowHiddenMetricsForVersion) > 0 {
metrics.SetShowHidden()
}
// About to get clients and such, detect standaloneMode
standaloneMode := true
if len(s.KubeConfig) > 0 {
standaloneMode = false
}View on GitHub (pinned to b882c60b40)
Solutions
- Check for a running kubelet: `pgrep -a kubelet` and `systemctl status kubelet` — stop duplicates.
- Confirm the lock-file directory exists and is writable by the kubelet user.
- If the prior process is truly dead but the lock lingers, remove the lock file and restart.
- On shared/read-only filesystems, move --lock-file-path to a local writable dir (e.g. /var/run).
Example fix
# before (read-only mount) --lock-file-path=/etc/kubernetes/kubelet.lock # after (local writable) --lock-file-path=/var/run/kubelet.lock
Defensive patterns
Strategy: validation
Validate before calling
// Preflight: confirm no other kubelet holds the lock and the dir is writable.
if running, _ := pgrepKubelet(); running {
return errors.New("kubelet already running; refusing to start a second instance")
} Prevention
- Place --lock-file-path on a local writable filesystem (e.g. /var/run), never a read-only mount.
- Use systemd as the single launcher to avoid double-starting kubelet.
When it happens
Trigger: Another kubelet process is already running and holds the lock; the lock-file path's directory does not exist or is not writable; permission denied on the path; or the filesystem does not support flock semantics.
Common situations: A second kubelet was started (double-launch); a previous kubelet crashed without releasing the lock and the stale lock is still held (rare with flock, which releases on process exit); --lock-file-path points at a read-only mount.
Related errors
- cannot exit on lock file contention: no lock file specified
- failed to walk through kubelet dropin directory %q: %w
- failed to load Kubelet config file %s, error %v
- failed to load drop-in kubelet config file %s, error %v
- kubelet unsupported in this build
AI-assisted analysis of kubernetes/kubernetes@b882c60b40 (2026-08-07).
Data as JSON: /api/errors/6231c7d2f9656a16.
Report an issue: GitHub.