cloudflare/cloudflared · error
found multiple tokens in the certificate
Error message
found multiple tokens in the certificate
What it means
Certificate-parsing error in decodeOriginCert: the origin cert PEM bundle contains more than one 'ARGO TUNNEL TOKEN' block. Only a single token block is valid; a second one means the file was concatenated or corrupted, and loading it is refused to avoid ambiguous credentials.
Source
Thrown at credentials/origin_cert.go:95
if err != nil {
return nil, fmt.Errorf("pem encoding failed: %v", err)
}
return out.Bytes(), nil
}
func decodeOriginCert(blocks []byte) (*OriginCert, error) {
if len(blocks) == 0 {
return nil, fmt.Errorf("cannot decode empty certificate")
}
originCert := OriginCert{}
block, rest := pem.Decode(blocks)
for block != nil {
switch block.Type {
case "PRIVATE KEY", "CERTIFICATE":
// this is for legacy purposes.
case "ARGO TUNNEL TOKEN":
if originCert.ZoneID != "" || originCert.APIToken != "" {
return nil, fmt.Errorf("found multiple tokens in the certificate")
}
// The token is a string,
// Try the newer JSON format
_ = json.Unmarshal(block.Bytes, &originCert)
default:
return nil, fmt.Errorf("unknown block %s in the certificate", block.Type)
}
block, rest = pem.Decode(rest)
}
if originCert.ZoneID == "" || originCert.APIToken == "" {
return nil, fmt.Errorf("missing token in the certificate")
}
return &originCert, nil
}
func readOriginCert(originCertPath string) ([]byte, error) {View on GitHub (pinned to 2253eeeb25)
Solutions
- Open the cert file and remove duplicate 'ARGO TUNNEL TOKEN' blocks, keeping only the current one
- Re-run 'cloudflared tunnel login' to regenerate a clean cert.pem
- Ensure deploy tooling overwrites rather than appends to the credentials file
Example fix
// before cat old-cert.pem new-cert.pem > cert.pem // after cp new-cert.pem cert.pem # keep exactly one ARGO TUNNEL TOKEN block
Defensive patterns
Strategy: validation
Validate before calling
count := strings.Count(string(pemBytes), "ARGO TUNNEL TOKEN")
if count > 1 { return errors.New("cert file has multiple token blocks") } Type guard
func hasSingleTokenBlock(pemBytes []byte) bool {
seen := 0
rest := pemBytes
for {
var b *pem.Block
b, rest = pem.Decode(rest)
if b == nil { return seen == 1 }
if b.Type == "ARGO TUNNEL TOKEN" { seen++ }
}
} Try / catch
cert, err := credentials.DecodeOriginCert(blocks)
if err != nil && strings.Contains(err.Error(), "multiple tokens") {
// flag file for manual cleanup / regenerate
} Prevention
- Never concatenate cert files; overwrite instead
- Regenerate via 'cloudflared tunnel login' rather than hand-editing
- Lint PEM bundles in CI for duplicate token blocks
When it happens
Trigger: PEM bundle passed to decodeOriginCert contains two or more 'ARGO TUNNEL TOKEN' blocks (second hit when originCert.ZoneID or originCert.APIToken is already set from a prior token block).
Common situations: Manually concatenated cert files; automation that appends tokens instead of replacing them; stale plus renewed token bundled in one .pem.
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.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- pem encoding failed: %v
- cannot decode empty certificate
- unknown block %s in the certificate
- missing token in the certificate
- parse CA certificate %s
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/28d4baec6feea3e6.
Report an issue: GitHub.