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.

Solutions

  1. Open the cert file and remove duplicate 'ARGO TUNNEL TOKEN' blocks, keeping only the current one
  2. Re-run 'cloudflared tunnel login' to regenerate a clean cert.pem
  3. 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

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.

Related errors


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

Appendix: 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)