cloudflare/cloudflared · error

Decoded tunnel secret must be at least 32 bytes long

Error message

Decoded tunnel secret must be at least 32 bytes long

What it means

When creating a Named Tunnel with a user-supplied secret (--tunnel-secret), create() base64-decodes it and enforces a minimum length of 32 bytes. A shorter decoded secret cannot be used as tunnel credentials, so creation is aborted.

Source

Thrown at cmd/cloudflared/tunnel/subcommand_context.go:145

	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{
		AccountTag:   credential.AccountID(),
		TunnelSecret: tunnelSecret,
		TunnelID:     tunnel.ID,
		Endpoint:     credential.Endpoint(),

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Generate a secret of at least 32 bytes before encoding, e.g. `head -c 32 /dev/urandom | base64`.
  2. Verify decoded length: `echo '<secret>' | base64 -d | wc -c` must be >= 32.
  3. Omit --secret and let cloudflared generate a compliant random secret automatically.

Example fix

// before
SECRET=$(echo -n "shortsecret" | base64)   # 10 bytes decoded
cloudflared tunnel create mytunnel --secret "$SECRET"
// after
SECRET=$(head -c 32 /dev/urandom | base64)  # 32 bytes decoded
cloudflared tunnel create mytunnel --secret "$SECRET"
Defensive patterns

Strategy: validation

Validate before calling

decoded, err := base64.StdEncoding.DecodeString(secret)
if err != nil {
    return fmt.Errorf("secret is not valid base64: %w", err)
}
if len(decoded) < 32 {
    return fmt.Errorf("secret decodes to %d bytes; need >= 32", len(decoded))
}

Prevention

When it happens

Trigger: Running `cloudflared tunnel create <name> --secret <base64>` where the decoded secret is under 32 bytes; using runAdhocNamedTunnel with a short secret.

Common situations: Hand-crafting secrets with short random strings; encoding a 16-byte value instead of 32; truncating generated secrets before base64 encoding.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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