{"record":{"id":"28cab8499b71d86c","repo":"cloudflare/cloudflared","slug":"write-token-to-s-w","errorCode":null,"errorMessage":"write token to %s: %w","messagePattern":"write token to (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/common_service.go","lineNumber":62,"sourceCode":"\treturn nil\n}\n\n// Write out the token file to the configuration directory with the correct\n// permissions. Since the method used to restrict the permissions is platform\n// dependent, make the function used to restrict the permissions an injectable\n// dependency\nfunc writeTokenToFile(path string, token string) error {\n\tif _, err := tunnel.ParseToken(token); err != nil {\n\t\treturn cliutil.UsageError(\"Provided tunnel token is not valid (%s).\", err)\n\t}\n\n\tif err := createTokenFile(path); err != nil {\n\t\treturn fmt.Errorf(\"create token file at %s: %w\", path, err)\n\t}\n\n\t// Won't update permissions as file already exists\n\tif err := os.WriteFile(path, []byte(token), 0o600); err != nil {\n\t\treturn fmt.Errorf(\"write token to %s: %w\", path, err)\n\t}\n\n\treturn nil\n}\n\nfunc removeTokenFile(configDir string, log *zerolog.Logger) {\n\ttp := tokenPath(configDir)\n\terr := os.Remove(tp)\n\n\tif err != nil && !errors.Is(err, os.ErrNotExist) {\n\t\tlog.Warn().Msgf(\"Could not remove service token file at %s: %v\", tp, err)\n\t}\n}\n\nfunc buildArgsForTokenFile(configDir string) []string {\n\treturn []string{\n\t\t\"tunnel\", \"run\", \"--token-file\", tokenPath(configDir),\n\t}","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/common_service.go#L44-L80","documentation":"This error wraps the failure of os.WriteFile when persisting an access token into the cloudflared configuration directory (path 0600). It is thrown by writeTokenToFile after the token file has been created, meaning the file exists but writing its contents failed. The wrapped error (%w) carries the underlying OS reason (permissions, disk full, etc.).","triggerScenarios":"Calling writeTokenToConfigDir (e.g. via `cloudflared tunnel token` or token-based service install) when os.WriteFile fails: filesystem became read-only, disk full, another process holds a conflicting lock, or the path is a directory/not writable despite createTokenFile succeeding.","commonSituations":"Disk quota exceeded on the host; /etc/cloudflared or user config dir on a read-only mount; token written concurrently by another cloudflared instance; SELinux/AppArmor blocking writes to the config directory.","solutions":["Check free disk space (df -h) and quotas; free space if full.","Verify the config directory permissions (e.g. /etc/cloudflared or ~/.cloudflared) allow writing as the current user: ls -ld <dir>.","Check the filesystem is not mounted read-only (mount | grep <dir>) and remount read-write.","Look at the wrapped OS error text in the log to identify the exact cause (EACCES, ENOSPC, etc.).","If security software (SELinux/AppArmor) is blocking writes, adjust policy or use a permitted config directory via --config."],"exampleFix":"// before: running as non-root user\ncloudflared tunnel token --cred-file /etc/cloudflared/token.json <tunnel>\n// after: run as root or point at a writable dir\nsudo cloudflared tunnel token --cred-file /etc/cloudflared/token.json <tunnel>","handlingStrategy":"try-catch","validationCode":"// before invoking install/token write\nif st, err := os.Stat(configDir); err != nil || !st.IsDir() { return fmt.Errorf(\"config dir %s missing\", configDir) }\nif err := unix.Access(configDir, unix.W_OK); err != nil { return fmt.Errorf(\"config dir %s not writable: %w\", configDir, err) }","typeGuard":"func isWritableDir(path string) bool {\n\tst, err := os.Stat(path)\n\treturn err == nil && st.IsDir() && unix.Access(path, unix.W_OK) == nil\n}","tryCatchPattern":"if err := writeTokenToConfigDir(ctx, dir); err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) {\n\t\tlog.Error().Str(\"op\", pe.Op).Str(\"path\", pe.Path).Err(pe.Err).Msg(\"token write failed\")\n\t}\n\treturn fmt.Errorf(\"token persistence failed: %w\", err)\n}","preventionTips":["Check disk space and directory writability before writing tokens.","Run with a user that owns or can write the config directory.","Avoid placing tokens on read-only or tmpfs-backed paths that get wiped.","Handle errors.As(fs.PathError) to surface the real OS cause."],"tags":["filesystem","token","file-write-failed","cloudflared"],"backgroundTag":"file-write-failed","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"}