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

  1. Run `cloudflared tunnel login` to obtain a valid origin certificate
  2. Verify ~/.cloudflared/cert.pem exists and is readable, or set TUNNEL_ORIGIN_CERT to a valid path
  3. Check api-url / TUNNEL_API_URL overrides for typos
  4. 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

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


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/0f56d2345134d695. Report an issue: GitHub.