cloudflare/cloudflared · error
Couldn't decode tunnel secret from base64
Error message
Couldn't decode tunnel secret from base64
What it means
When a tunnel secret is supplied via --secret, create() decodes it from base64; if base64.StdEncoding.DecodeString fails, this wrapped error is returned. The secret must be valid standard-base64 and at least 32 bytes once decoded.
Source
Thrown at cmd/cloudflared/tunnel/subcommand_context.go:141
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")
}
}
tunnel, err := client.CreateTunnel(name, tunnelSecret)
if err != nil {
return nil, errors.Wrap(err, "Create Tunnel API call failed")
}
credential, err := sc.credential()
if err != nil {
return nil, err
}
tunnelCredentials := connection.Credentials{View on GitHub (pinned to 2253eeeb25)
Solutions
- Regenerate the secret as standard base64 of >=32 random bytes: `head -c 32 /dev/urandom | base64`
- Quote the secret in the shell to avoid character mangling
- If the value uses URL-safe base64, convert it (replace -/_, restore padding) to standard base64
- Ensure no trailing newline/whitespace is included (e.g. strip with tr -d '\n')
Example fix
// before cloudflared tunnel create --secret "abc-123_xyz" mytunnel // after SECRET=$(head -c 32 /dev/urandom | base64) cloudflared tunnel create --secret "$SECRET" mytunnel
Defensive patterns
Strategy: validation
Validate before calling
decoded, err := base64.StdEncoding.DecodeString(secret)
if err != nil {
return fmt.Errorf("--secret must be standard base64: %w", err)
}
if len(decoded) < 32 {
return fmt.Errorf("--secret must decode to at least 32 bytes, got %d", len(decoded))
} Prevention
- Generate secrets with `head -c 32 /dev/urandom | base64`
- Quote secrets in shell to prevent mangling
- Strip whitespace/newlines from secret files
When it happens
Trigger: `cloudflared tunnel create --secret <value>` where <value> contains characters outside the standard base64 alphabet or wrong padding.
Common situations: Passing a URL-safe base64 string (with - and _) instead of standard base64; trailing whitespace/newlines; shell mangling of special characters; reusing a raw hex or plaintext string as the secret.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid CIDR supplied for %s
- invalid connection override: %s
- not a valid host
- no input provided
- failed to parse Host
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/79f87ecf94a4f769.
Report an issue: GitHub.