cloudflare/cloudflared · error
couldn't create client to talk to Cloudflare Tunnel backend
Error message
couldn't create client to talk to Cloudflare Tunnel backend
What it means
create() could not construct the Cloudflare API client (sc.client()). The client is built from the account token/origincert and API URL; any failure assembling it (bad credentials source, config, or HTTP client setup) is wrapped with this message.
Source
Thrown at cmd/cloudflared/tunnel/subcommand_context.go:129
}
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 {
return nil, errors.Wrap(err, "couldn't create client to talk to Cloudflare Tunnel backend")
}
var tunnelSecret []byte
if secret == "" {
tunnelSecret, err = generateTunnelSecret()
if err != nil {
return nil, errors.Wrap(err, "couldn't generate the secret for your new tunnel")
}
} else {
decodedSecret, err := base64.StdEncoding.DecodeString(secret)
if err != nil {
return nil, errors.Wrap(err, "Couldn't decode tunnel secret from base64")
}
tunnelSecret = decodedSecret
if len(tunnelSecret) < 32 {
return nil, errors.New("Decoded tunnel secret must be at least 32 bytes long")
}
}View on GitHub (pinned to 2253eeeb25)
Solutions
- Run `cloudflared tunnel login` to obtain a valid origin certificate
- Verify ~/.cloudflared/cert.pem exists and is readable, or set TUNNEL_ORIGIN_CERT to a valid path
- Check api-url / TUNNEL_API_URL overrides for typos
- Ensure the cert matches an account you can create tunnels in
Example fix
// before $ cloudflared tunnel create mytunnel # no cert.pem // after $ cloudflared tunnel login $ cloudflared tunnel create mytunnel
Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.Stat(certPath); os.IsNotExist(err) {
return fmt.Errorf("run `cloudflared tunnel login` first; %s not found", certPath)
} Prevention
- Run `cloudflared tunnel login` before tunnel create in CI/VMs
- Set TUNNEL_ORIGIN_CERT explicitly in automation
- Verify api-url overrides
When it happens
Trigger: sc.client() returns an error inside subcommandContext.create, invoked by runAdhocNamedTunnel (`cloudflared tunnel create <name>`).
Common situations: Missing or invalid ~/.cloudflared/cert.pem (not logged in with `cloudflared tunnel login`); malformed api-url override; TUNNEL_TOKEN vs cert confusion in CI environments.
Related errors
- ErrUnauthorized
- ErrBadRequest
- failed to unmarshal quick Tunnel
- failed to parse quick Tunnel ID
- Create Tunnel API call failed
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/0f56d2345134d695.
Report an issue: GitHub.