cloudflare/cloudflared · error
couldn't read tunnel credentials from %v
Error message
couldn't read tunnel credentials from %v
What it means
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.
Source
Thrown at cmd/cloudflared/tunnel/subcommand_context.go:110
func (sc *subcommandContext) credential() (*credentials.User, error) {
if sc.userCredential == nil {
uc, err := credentials.Read(sc.c.String(cfdflags.OriginCert), sc.log)
if err != nil {
return nil, err
}
sc.userCredential = uc
}
return sc.userCredential, nil
}
func (sc *subcommandContext) readTunnelCredentials(credFinder CredFinder) (connection.Credentials, error) {
filePath, err := credFinder.Path()
if err != nil {
return connection.Credentials{}, err
}
body, err := sc.fs.readFile(filePath)
if err != nil {
return connection.Credentials{}, errors.Wrapf(err, "couldn't read tunnel credentials from %v", filePath)
}
var credentials connection.Credentials
if err = json.Unmarshal(body, &credentials); err != nil {
if filepath.Ext(filePath) == ".pem" {
return connection.Credentials{}, fmt.Errorf("The tunnel credentials file should be .json but you gave a .pem. " +
"The tunnel credentials file was originally created by `cloudflared tunnel create`. " +
"You may have accidentally used the filepath to cert.pem, which is generated by `cloudflared tunnel " +
"login`.")
}
return connection.Credentials{}, invalidJSONCredentialError{path: filePath, err: err}
}
return credentials, nil
}
func (sc *subcommandContext) create(name string, credentialsFilePath string, secret string) (*cfapi.Tunnel, error) {
client, err := sc.client()
if err != nil {View on GitHub (pinned to 2253eeeb25)
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
Example fix
// before cloudflared tunnel run --cred-file /etc/cloudflared/wrong.json mytunnel // after cloudflared tunnel run --cred-file /etc/cloudflared/mytunnel.json mytunnel
Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.Stat(credPath); err != nil {
return fmt.Errorf("credentials file missing/unreadable: %w", err)
}
if f, err := os.Open(credPath); err != nil {
return fmt.Errorf("no read permission for %s: %w", credPath, err)
} else { f.Close() } Try / catch
if err := runTunnel(...); err != nil {
if strings.Contains(err.Error(), "couldn't read tunnel credentials") {
// check path exists and re-provision token before crashing
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- %s already exists
- No configuration file was found. Please create one, or use t
- Invalid CIDR supplied for %s
- invalid connection override: %s
- failed to build quick tunnel request
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/1b191b42c1b68712.
Report an issue: GitHub.