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

  1. Ensure the token directory exists and is writable: mkdir -p ~/.cloudflared && chown -R $USER ~/.cloudflared
  2. If cloudflared was ever run with sudo, fix ownership of files it created (sudo chown -R $USER ~/.cloudflared)
  3. Check disk space (df -h) and filesystem mount state (read-only remount)
  4. 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

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


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/e9e8d2dc07617d5a. Report an issue: GitHub.