{"record":{"id":"3afa5e898249ab9b","repo":"cloudflare/cloudflared","slug":"failed-to-acquire-org-token-lock","errorCode":null,"errorMessage":"failed to acquire org token lock","messagePattern":"failed to acquire org token lock","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"token/token.go","lineNumber":368,"sourceCode":"\tdefer appTokenLock.release()\n\n\t// check to see if another process has gotten a token while we waited for the lock\n\tif token, err := GetAppTokenIfExists(appInfo); token != \"\" && err == nil {\n\t\treturn token, nil\n\t}\n\n\t// If an app token couldn't be found on disk, check for an org token and attempt to exchange it for an app token.\n\tvar orgTokenPath string\n\torgToken, orgTokenErr := GetOrgTokenIfExists(appInfo.AuthDomain)\n\tif orgTokenErr != nil {\n\t\torgTokenPath, err = generateOrgTokenFilePathFromURL(appInfo.AuthDomain)\n\t\tif err != nil {\n\t\t\treturn \"\", errors.Wrap(err, \"failed to generate org token file path\")\n\t\t}\n\n\t\torgTokenLock, orgLockErr := acquireLockFile(orgTokenPath, log)\n\t\tif orgLockErr != nil {\n\t\t\treturn \"\", errors.Wrap(orgLockErr, \"failed to acquire org token lock\")\n\t\t}\n\t\tdefer orgTokenLock.release()\n\t\t// check if an org token has been created since the lock was acquired\n\t\torgToken, orgTokenErr = GetOrgTokenIfExists(appInfo.AuthDomain)\n\t}\n\tif orgTokenErr == nil {\n\t\tif appToken, exchangeErr := exchangeOrgToken(appURL, orgToken); exchangeErr != nil {\n\t\t\tlog.Debug().Msgf(\"failed to exchange org token for app token: %s\", exchangeErr)\n\t\t} else {\n\t\t\t// generate app path\n\t\t\tif err := os.WriteFile(appTokenPath, []byte(appToken), 0600); err != nil { // nolint: gosec\n\t\t\t\treturn \"\", errors.Wrap(err, \"failed to write app token to disk\")\n\t\t\t}\n\t\t\treturn appToken, nil\n\t\t}\n\t}\n\treturn getTokensFromEdge(appURL, appInfo.AppAUD, appTokenPath, orgTokenPath, useHostOnly, autoClose, isFedramp, log)\n}","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/token/token.go#L350-L386","documentation":"getToken wraps this error when acquireLockFile fails to create the org-token lock file with a non-EEXIST error. The org lock ensures only one process performs the org-token exchange and subsequent app-token write for the auth domain. Without the lock, the exchange flow aborts.","triggerScenarios":"FetchToken / FetchTokenWithRedirect -> getToken -> acquireLockFile(orgTokenPath) failing due to real filesystem errors: unwritable directory, missing parent directories, disk full, or restrictive umask/permissions on ~/.cloudflared.","commonSituations":"Multi-user systems where the daemon user differs from the user who created ~/.cloudflared; read-only container filesystems; NFS-mounted home directories with locking quirks; disk exhaustion on small VMs.","solutions":["Ensure the token directory exists and is writable by the running user (mkdir -p, chown)","Run cloudflared consistently under one user; fix ownership after any sudo runs","Check disk space and mount flags (df -h, mount | grep home)","Read the wrapped cause for the precise errno (EACCES/ENOENT/ENOSPC) and fix that condition"],"exampleFix":"// systemd unit: pin the user and pre-create the token dir\n[Service]\nUser=cloudflared\nExecStartPre=/usr/bin/mkdir -p /home/cloudflared/.cloudflared\nExecStartPre=/bin/chown cloudflared:cloudflared /home/cloudflared/.cloudflared","handlingStrategy":"validation","validationCode":"// preflight: directory exists, owned by me, writable\ninfo, err := os.Stat(tokenDir)\nif err != nil || !info.IsDir() {\n\tos.MkdirAll(tokenDir, 0700)\n}\nif err := syscall.Access(tokenDir, syscall.W_OK); err != nil {\n\treturn fmt.Errorf(\"cannot write org-token lock in %s: %v\", tokenDir, err)\n}","typeGuard":null,"tryCatchPattern":"token, err := FetchToken(...)\nif err != nil && strings.Contains(err.Error(), \"failed to acquire org token lock\") {\n\t// filesystem-level failure; advise chown/mkdir, not retry\n\treturn fmt.Errorf(\"%w — ensure %s is writable by the service user\", err, tokenDir)\n}","preventionTips":["Pre-create the token directory in service startup scripts","Avoid NFS home dirs for the cloudflared service user","Set umask so 0600/0700 files are creatable","Alert on EACCES/ENOSPC in daemon logs"],"tags":["filesystem","file-lock","permissions","token"],"backgroundTag":"file-write-permission-denied","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}