{"record":{"id":"1f3972e7bbf13052","repo":"cloudflare/cloudflared","slug":"missing-token-in-the-certificate","errorCode":null,"errorMessage":"missing token in the certificate","messagePattern":"missing token in the certificate","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/origin_cert.go","lineNumber":107,"sourceCode":"\tfor block != nil {\n\t\tswitch block.Type {\n\t\tcase \"PRIVATE KEY\", \"CERTIFICATE\":\n\t\t\t// this is for legacy purposes.\n\t\tcase \"ARGO TUNNEL TOKEN\":\n\t\t\tif originCert.ZoneID != \"\" || originCert.APIToken != \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"found multiple tokens in the certificate\")\n\t\t\t}\n\t\t\t// The token is a string,\n\t\t\t// Try the newer JSON format\n\t\t\t_ = json.Unmarshal(block.Bytes, &originCert)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unknown block %s in the certificate\", block.Type)\n\t\t}\n\t\tblock, rest = pem.Decode(rest)\n\t}\n\n\tif originCert.ZoneID == \"\" || originCert.APIToken == \"\" {\n\t\treturn nil, fmt.Errorf(\"missing token in the certificate\")\n\t}\n\n\treturn &originCert, nil\n}\n\nfunc readOriginCert(originCertPath string) ([]byte, error) {\n\toriginCert, err := os.ReadFile(originCertPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot read %s to load origin certificate\", originCertPath)\n\t}\n\n\treturn originCert, nil\n}\n\n// FindOriginCert will check to make sure that the certificate exists at the specified file path.\nfunc FindOriginCert(originCertPath string, log *zerolog.Logger) (string, error) {\n\tif originCertPath == \"\" {\n\t\tlog.Error().Msgf(\"Cannot determine default origin certificate path. No file %s in %v. You need to specify the origin certificate path by specifying the origincert option in the configuration file, or set TUNNEL_ORIGIN_CERT environment variable\", DefaultCredentialFile, config.DefaultConfigSearchDirectories())","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/credentials/origin_cert.go#L89-L125","documentation":"After decoding all PEM blocks, decodeOriginCert requires both ZoneID and APIToken to have been populated (normally by the ARGO TUNNEL TOKEN block). If either is missing the cert is unusable for tunnel authentication.","triggerScenarios":"PEM bundle has no 'ARGO TUNNEL TOKEN' block, or the token block's JSON payload lacks zoneID/apiToken fields (empty or wrong-shaped JSON silently unmarshaled).","commonSituations":"Cert regenerated by newer cloudflared but old tooling expects fields; token block present but JSON malformed (json.Unmarshal error is intentionally ignored); user hand-built the cert.","solutions":["Re-run 'cloudflared tunnel login' to obtain a complete cert.pem containing the token block","Verify the ARGO TUNNEL TOKEN block's base64/PEM payload decodes to JSON with zoneID and apiToken keys","Check for cloudflared version mismatch between the tool that created the cert and the one consuming it"],"exampleFix":"// before\n_ = json.Unmarshal(block.Bytes, &originCert)\n// after (upstream fix suggestion)\nif err := json.Unmarshal(block.Bytes, &originCert); err != nil {\n\treturn nil, fmt.Errorf(\"failed to decode ARGO TUNNEL TOKEN: %w\", err)\n}","handlingStrategy":"validation","validationCode":"rest := pemBytes\nhasToken := false\nfor {\n\tb, r := pem.Decode(rest)\n\tif b == nil { break }\n\tif b.Type == \"ARGO TUNNEL TOKEN\" {\n\t\tvar probe map[string]json.RawMessage\n\t\tif json.Unmarshal(b.Bytes, &probe) == nil && len(probe[\"zoneID\"]) > 0 && len(probe[\"apiToken\"]) > 0 {\n\t\t\thasToken = true\n\t\t}\n\t}\n\trest = r\n}\nif !hasToken { return errors.New(\"cert lacks a valid ARGO TUNNEL TOKEN block\") }","typeGuard":null,"tryCatchPattern":"cert, err := credentials.DecodeOriginCert(blocks)\nif err != nil && strings.Contains(err.Error(), \"missing token\") {\n\t// trigger 'cloudflared tunnel login' flow\n}","preventionTips":["Always obtain cert.pem via 'cloudflared tunnel login'","After any cert regeneration, re-run a decode smoke test","Keep cloudflared versions consistent across cert producers/consumers"],"tags":["pem","certificate","missing-token"],"backgroundTag":"missing-credentials","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}