{"record":{"id":"519d202d6f33299e","repo":"cloudflare/cloudflared","slug":"could-not-write-token-to-configuration-directory","errorCode":null,"errorMessage":"could not write token to configuration directory: %w","messagePattern":"could not write token to configuration directory: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/linux_service.go","lineNumber":287,"sourceCode":"\t\t// no config exists).\n\t\tif extraArgs, err = buildArgsForConfig(c, log); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// If passed one argument e.g., \"$ cloudflared service install <token>\"\n\t\t// write the token to the config directory and install the service\n\t\t// using --token-file pointing to that file. This is the quick setup\n\t\t// the tunnel UI suggests.\n\n\t\t// Ensure token file is removed if install fails\n\t\tdefer func() {\n\t\t\tif err != nil {\n\t\t\t\tremoveTokenFile(serviceConfigDir, log)\n\t\t\t}\n\t\t}()\n\n\t\tif err = writeTokenToConfigDir(c, serviceConfigDir); err != nil {\n\t\t\treturn fmt.Errorf(\"could not write token to configuration directory: %w\", err)\n\t\t}\n\n\t\textraArgs = buildArgsForTokenFile(serviceConfigDir)\n\t}\n\n\ttemplateArgs.ExtraArgs = extraArgs\n\n\t// Check if the \"no update flag\" is set\n\tautoUpdate := !c.IsSet(noUpdateServiceFlag.Name)\n\n\tswitch {\n\tcase inits.IsSystemd():\n\t\tlog.Info().Msgf(\"Using Systemd\")\n\t\terr = installSystemd(&templateArgs, autoUpdate, log)\n\tcase inits.IsOpenRC():\n\t\tlog.Info().Msgf(\"Using OpenRC\")\n\t\terr = installOpenRC(&templateArgs, autoUpdate)\n\tdefault:","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/linux_service.go#L269-L305","documentation":"In token-based `cloudflared service install` on Linux, after creating the service config directory cloudflared writes the tunnel token there via writeTokenToConfigDir. If that write fails for any reason, installLinuxService aborts and wraps the failure with this message; the underlying cause (from error 115's chain) is preserved via %w. A deferred removeTokenFile cleans up the partial directory.","triggerScenarios":"Running `cloudflared service install --token <token>` when the token cannot be written to /etc/cloudflared (or the chosen config dir): permission denied for the non-root user, read-only filesystem, disk full, or directory creation/write failure.","commonSituations":"Forgetting sudo/root before service install (system config dir requires root); /etc on a read-only root filesystem in immutable containers; full disk on small VPS instances; SELinux policies blocking writes to /etc/cloudflared.","solutions":["Re-run the install with elevated privileges: `sudo cloudflared service install --token <token>` — /etc/cloudflared typically requires root.","Inspect the wrapped underlying error in the output (permission denied vs no space) and address it specifically.","Verify the config directory is writable: `ls -ld /etc/cloudflared && sudo -u <user> touch /etc/cloudflared/.probe`.","Ensure the filesystem is writable and has free space (df -h; mount).","As a fallback, place the token file manually and run service install pointing at it, or run the tunnel in the foreground with --token."],"exampleFix":"// before\ncloudflared service install --token <token>\n// error: could not write token to configuration directory\n// after\nsudo cloudflared service install --token <token>","handlingStrategy":"validation","validationCode":"// preflight before token-based service install\nif os.Geteuid() != 0 {\n\treturn errors.New(\"token-based service install requires root to write /etc/cloudflared\")\n}\nif unix.Access(\"/etc\", unix.W_OK) != nil {\n\treturn errors.New(\"/etc is not writable (read-only fs?)\")\n}","typeGuard":"func tokenWritablePreflight(dir string) bool {\n\treturn os.Geteuid() == 0 && unix.Access(filepath.Dir(dir), unix.W_OK) == nil\n}","tryCatchPattern":"if err := writeTokenToConfigDir(ctx, dir); err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) && errors.Is(pe.Err, os.ErrPermission) {\n\t\treturn fmt.Errorf(\"re-run with sudo: %w\", err)\n\t}\n\treturn fmt.Errorf(\"could not write token to configuration directory: %w\", err)\n}","preventionTips":["Run token-based `service install` as root (sudo) — system config dirs require it.","Verify disk space and that /etc is on a writable filesystem.","Check the deferred removeTokenFile cleanup log to confirm no partial token files remain after failure.","On immutable/container images, pass the token via a mounted writable volume or run in the foreground with --token instead."],"tags":["linux","service","token","permission-denied","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-14T00:17:10.932Z"}