{"record":{"id":"5d5219f911729ba1","repo":"cloudflare/cloudflared","slug":"error-writing-cert-to-s","errorCode":null,"errorMessage":"error writing cert to %s","messagePattern":"error writing cert to (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/tunnel/login.go","lineNumber":127,"sourceCode":"\n\tcert, err := credentials.DecodeOriginCert(resourceData)\n\tif err != nil {\n\t\tlog.Error().Err(err).Msg(\"failed to decode origin certificate\")\n\t\treturn err\n\t}\n\n\tif isFEDRamp {\n\t\tcert.Endpoint = credentials.FedEndpoint\n\t}\n\n\tresourceData, err = cert.EncodeOriginCert()\n\tif err != nil {\n\t\tlog.Error().Err(err).Msg(\"failed to encode origin certificate\")\n\t\treturn err\n\t}\n\n\tif err := os.WriteFile(path, resourceData, 0600); err != nil { // nolint: gosec\n\t\treturn errors.Wrap(err, fmt.Sprintf(\"error writing cert to %s\", path))\n\t}\n\n\tlog.Info().Msgf(\"You have successfully logged in.\\nIf you wish to copy your credentials to a server, they have been saved to:\\n%s\\n\", path)\n\treturn nil\n}\n\nfunc checkForExistingCert() (string, bool, error) {\n\tconfigPath, err := homedir.Expand(config.DefaultConfigSearchDirectories()[0])\n\tif err != nil {\n\t\treturn \"\", false, err\n\t}\n\tok, err := config.FileExists(configPath)\n\tif !ok && err == nil {\n\t\t// create config directory if doesn't already exist\n\t\terr = os.Mkdir(configPath, 0700)\n\t}\n\tif err != nil {\n\t\treturn \"\", false, err","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/tunnel/login.go#L109-L145","documentation":"After `cloudflared tunnel login` fetches and encodes the origin certificate, it writes the PEM data to the target path with os.WriteFile. If the write fails (bad directory, permissions, disk full) the error is wrapped as 'error writing cert to <path>'. Login cannot complete without persisting the certificate.","triggerScenarios":"Running `cloudflared tunnel login --origincert /some/path` where /some/path's directory does not exist, the file is not writable, or the filesystem is read-only/full.","commonSituations":"Custom --origincert paths in non-existent directories; running as non-root in a root-owned directory; read-only container filesystems; disk quota exceeded in home directories.","solutions":["Create the parent directory of the cert path (mkdir -p) before running login.","Ensure the user running cloudflared has write permission to the path (chown/chmod or run with proper privileges).","Check free disk space and that the filesystem is not mounted read-only.","Choose a different writable --origincert path (default ~/.cloudflared/cert.pem)."],"exampleFix":"// before\ncloudflared tunnel login --origincert /etc/cloudflared/cert.pem  # dir missing\n// after\nmkdir -p /etc/cloudflared && chmod 755 /etc/cloudflared\ncloudflared tunnel login --origincert /etc/cloudflared/cert.pem","handlingStrategy":"validation","validationCode":"// ensure the cert destination is writable before login\nimport os\nfunc certPathWritable(path string) error {\n\tdir := filepath.Dir(path)\n\tif err := os.MkdirAll(dir, 0755); err != nil { return err }\n\tf, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0600)\n\tif err != nil { return err }\n\t_ = f.Close()\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err := os.WriteFile(path, resourceData, 0600); err != nil {\n\treturn errors.Wrap(err, fmt.Sprintf(\"error writing cert to %s\", path))\n}","preventionTips":["Create ~/.cloudflared (or custom dir) with correct ownership before login","Run login as the same user that will run cloudflared","Check disk space and read-only mounts in containers","Stick to the default cert path unless you have a specific need"],"tags":["filesystem","certificates","permissions","cli"],"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"}