{"record":{"id":"1b191b42c1b68712","repo":"cloudflare/cloudflared","slug":"couldn-t-read-tunnel-credentials-from-v","errorCode":null,"errorMessage":"couldn't read tunnel credentials from %v","messagePattern":"couldn't read tunnel credentials from (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/tunnel/subcommand_context.go","lineNumber":110,"sourceCode":"func (sc *subcommandContext) credential() (*credentials.User, error) {\n\tif sc.userCredential == nil {\n\t\tuc, err := credentials.Read(sc.c.String(cfdflags.OriginCert), sc.log)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsc.userCredential = uc\n\t}\n\treturn sc.userCredential, nil\n}\n\nfunc (sc *subcommandContext) readTunnelCredentials(credFinder CredFinder) (connection.Credentials, error) {\n\tfilePath, err := credFinder.Path()\n\tif err != nil {\n\t\treturn connection.Credentials{}, err\n\t}\n\tbody, err := sc.fs.readFile(filePath)\n\tif err != nil {\n\t\treturn connection.Credentials{}, errors.Wrapf(err, \"couldn't read tunnel credentials from %v\", filePath)\n\t}\n\n\tvar credentials connection.Credentials\n\tif err = json.Unmarshal(body, &credentials); err != nil {\n\t\tif filepath.Ext(filePath) == \".pem\" {\n\t\t\treturn connection.Credentials{}, fmt.Errorf(\"The tunnel credentials file should be .json but you gave a .pem. \" +\n\t\t\t\t\"The tunnel credentials file was originally created by `cloudflared tunnel create`. \" +\n\t\t\t\t\"You may have accidentally used the filepath to cert.pem, which is generated by `cloudflared tunnel \" +\n\t\t\t\t\"login`.\")\n\t\t}\n\t\treturn connection.Credentials{}, invalidJSONCredentialError{path: filePath, err: err}\n\t}\n\treturn credentials, nil\n}\n\nfunc (sc *subcommandContext) create(name string, credentialsFilePath string, secret string) (*cfapi.Tunnel, error) {\n\tclient, err := sc.client()\n\tif err != nil {","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/tunnel/subcommand_context.go#L92-L128","documentation":"readTunnelCredentials could not read the tunnel credentials file from disk. The resolved path (via credFinder) exists logically per the finder, but reading its bytes failed. The message includes the offending file path.","triggerScenarios":"sc.fs.readFile(filePath) fails in readTunnelCredentials, reached from `cloudflared tunnel tunnel run <name>` (findCredentials) or `tunnel info`/delete flows via findID, when the --cred-file path is unreadable.","commonSituations":"Credentials file deleted or moved after tunnel creation; wrong path passed via --cred-file; running cloudflared as a different user (systemd service) lacking read permission; Docker/container volume not mounted.","solutions":["Verify the path printed in the error exists: `ls -l <path>`","Fix permissions so the cloudflared process user can read it (e.g. `chown`/`chmod 600`)","Re-run `cloudflared tunnel token <name>` to regenerate the credentials JSON file","If the file is truly gone, delete and recreate the tunnel: `cloudflared tunnel create <name>`","In containers, ensure the credentials file is mounted into the container"],"exampleFix":"// before\ncloudflared tunnel run --cred-file /etc/cloudflared/wrong.json mytunnel\n// after\ncloudflared tunnel run --cred-file /etc/cloudflared/mytunnel.json mytunnel","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(credPath); err != nil {\n    return fmt.Errorf(\"credentials file missing/unreadable: %w\", err)\n}\nif f, err := os.Open(credPath); err != nil {\n    return fmt.Errorf(\"no read permission for %s: %w\", credPath, err)\n} else { f.Close() }","typeGuard":null,"tryCatchPattern":"if err := runTunnel(...); err != nil {\n    if strings.Contains(err.Error(), \"couldn't read tunnel credentials\") {\n        // check path exists and re-provision token before crashing\n    }\n    return err\n}","preventionTips":["Pass --cred-file with an absolute, verified path","Ensure the service user (systemd/container) can read the file","Mount credentials into containers explicitly","Re-run `cloudflared tunnel token <name>` after file loss"],"tags":["go","file","credentials","cli"],"backgroundTag":"file-read-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"}