cloudflare/cloudflared · error
failed to create lock file %s
Error message
failed to create lock file %s
What it means
This error comes from acquireLockFile when creating the cloudflared token lock file fails with an error other than 'already exists' — i.e. a real filesystem failure, not benign contention. The lock file (created with O_CREAT|O_EXCL semantics) prevents multiple cloudflared processes from racing to fetch the same token. Non-EEXIST failures are wrapped so the caller knows lock acquisition was impossible.
Source
Thrown at token/token.go:137
// 3. If the owner is alive, sleep for lockRetryInterval and retry.
// 4. If the owner is dead (stale lock), remove the file and immediately
// retry the O_EXCL create. No sleep (the atomic create is the
// tiebreaker if multiple processes race to reclaim).
func acquireLockFile(tokenPath string, log *zerolog.Logger) (*lockFile, error) {
lockPath := tokenPath + ".lock"
deadline := time.Now().Add(lockTimeout)
lastURL := ""
for {
if time.Now().After(deadline) {
return nil, fmt.Errorf("timed out waiting for lock file %s", lockPath)
}
content, err := createLockFile(lockPath)
if err == nil {
log.Debug().Str("path", lockPath).Msg("lock file acquired")
return &lockFile{path: lockPath, content: content, log: log}, nil
}
if !os.IsExist(err) {
return nil, errors.Wrapf(err, "failed to create lock file %s", lockPath)
}
// lock file exists, so check if the owner is still alive
stale, content, checkErr := isLockFileStale(lockPath)
if checkErr != nil {
// file may be mid-write by another racer, or was removed
// between our O_EXCL attempt and this read
log.Debug().Err(checkErr).Str("path", lockPath).
Msg("could not read lock file, retrying")
time.Sleep(lockRetryInterval)
continue
}
if !stale {
// try to display the auth URL so the user can open a browser
// manually if the original window is not visible
if authURL := readAuthURL(tokenPath); authURL != "" && authURL != lastURL {
fmt.Fprintf(os.Stderr, "\nAnother cloudflared process (pid %d) "+View on GitHub (pinned to 2253eeeb25)
Solutions
- Ensure the token directory exists and is writable: mkdir -p ~/.cloudflared && chown -R $USER ~/.cloudflared
- If cloudflared was ever run with sudo, fix ownership of files it created (sudo chown -R $USER ~/.cloudflared)
- Check disk space (df -h) and filesystem mount state (read-only remount)
- Read the wrapped underlying error to identify whether it is EACCES, ENOSPC, ENOENT, or EPERM and address accordingly
Example fix
// before: failing when the token directory is missing
lock, err := acquireLockFile(appTokenPath, log)
// after: ensure the directory exists before locking
if err := os.MkdirAll(filepath.Dir(appTokenPath), 0700); err != nil {
return "", errors.Wrap(err, "failed to create token directory")
}
lock, err := acquireLockFile(appTokenPath, log) Defensive patterns
Strategy: validation
Validate before calling
// check the token directory is writable before running
import "os"
if err := checkDirWritable(os.UserHomeDir + "/.cloudflared"); err != nil {
log.Fatal(err) // fix ownership/permissions first
} Try / catch
lock, err := acquireLockFile(path, log)
if err != nil && strings.Contains(err.Error(), "failed to create lock file") {
// real FS failure (EACCES/ENOSPC): do NOT retry blindly; surface to operator
return fmt.Errorf("cannot lock token storage: %w — check ~/.cloudflared permissions", err)
} Prevention
- Never mix sudo and non-sudo cloudflared runs; chown ~/.cloudflared afterwards
- Pre-create ~/.cloudflared with 0700 owned by the service user
- Monitor disk space on hosts running cloudflared
- Run cloudflared under a dedicated user with a stable HOME
When it happens
Trigger: getToken -> acquireLockFile where createLockFile fails for reasons other than os.IsExist: the token directory does not exist, the process lacks write permission on the directory (e.g. ~/.cloudflared owned by root), the disk is full, or the path is invalid/too long.
Common situations: Running cloudflared with a HOME it cannot write to; ~/.cloudflared created previously by a root-run instance so a non-root user cannot create files; read-only home volume or container filesystem; AppArmor/SELinux denying writes to the token directory.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- failed to acquire app token lock
- failed to acquire org token lock
- failed to write app token to disk
- failed to write org token to disk
- The file-writing error is: %v / The delete tunnel error is:
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/e9e8d2dc07617d5a.
Report an issue: GitHub.