{"record":{"id":"cf900875208c3476","repo":"OpenNHP/opennhp","slug":"failed-to-parse-token-w","errorCode":null,"errorMessage":"failed to parse token: %w","messagePattern":"failed to parse token: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/server/kbs/resource/resource.go","lineNumber":216,"sourceCode":"\t\treturn nil, nil, nil, err\n\t}\n\n\tiv = make([]byte, gcm.NonceSize())\n\tif _, err = io.ReadFull(rand.Reader, iv); err != nil {\n\t\treturn nil, nil, nil, err\n\t}\n\n\tciphertext = gcm.Seal(nil, iv, plaintext, nil)\n\n\treturn ciphertext, iv, nil, nil\n}\n\nfunc VerifyJWT(tokenString string) (*jwt.Token, error) {\n\t// First parse the token without verification to get the header\n\tparser := jwt.NewParser()\n\tunverifiedToken, _, err := parser.ParseUnverified(tokenString, jwt.MapClaims{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse token: %w\", err)\n\t}\n\n\t// Extract JWK from header\n\tjwkHeader, ok := unverifiedToken.Header[\"jwk\"].(map[string]any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"missing or invalid jwk in header\")\n\t}\n\n\t// Convert JWK back to ECDSA public key\n\txStr, ok := jwkHeader[\"x\"].(string)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"missing x coordinate in jwk\")\n\t}\n\tyStr, ok := jwkHeader[\"y\"].(string)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"missing y coordinate in jwk\")\n\t}\n","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/kbs/resource/resource.go#L198-L234","documentation":"VerifyJWT first parses the JWT with ParseUnverified solely to inspect the header; if the token string is malformed (bad base64, invalid JSON segments, wrong compact form), it returns 'failed to parse token: %w'. This is a pre-verification structural check before extracting the embedded JWK. The wrapped go-jose/jwt error names the exact defect.","triggerScenarios":"GetResource is called with an Authorization token that is not a well-formed three-part JWT: truncated token, non-base64url characters, malformed JSON in header/payload, empty string, or extra segments.","commonSituations":"Client sends a raw API key or an opaque session token instead of a JWT; token truncated by an intermediary (header size limits, proxy mangling); wrong encoding (standard base64 with padding instead of base64url); missing 'Bearer ' prefix handling leaving stray text.","solutions":["Log/print the token structure: it must have exactly three dot-separated base64url segments.","Fix the client to emit a valid ES256 JWT signed per the COSE/JWK-embedded scheme.","Check for proxy or framework munging of the Authorization header (line folding, truncation).","Ensure no whitespace/newlines are embedded in the token string.","Decode each segment offline (e.g. `base64 -d` after padding) to find the malformed part."],"exampleFix":"// client side: ensure compact JWS serialization, three base64url segments\n// before: sending raw key material\ntoken := base64.StdEncoding.EncodeToString(keyBytes)\n// after: produce a properly signed JWT\ntoken := jwt.NewWithClaims(jwt.SigningMethodES256, claims)\ns, _ := token.SignedString(privateKey)","handlingStrategy":"validation","validationCode":"func looksLikeJWT(token string) bool {\n\tparts := strings.Split(token, \".\")\n\tif len(parts) != 3 { return false }\n\tfor _, p := range parts {\n\t\tif _, err := base64.RawURLEncoding.DecodeString(p); err != nil { return false }\n\t}\n\treturn true\n}\n// call looksLikeJWT(token) before VerifyJWT","typeGuard":"func isWellFormedJWS(s string) bool { return strings.Count(s, \".\") == 2 && len(s) > 0 }","tryCatchPattern":"token, err := VerifyJWT(rawToken)\nif err != nil {\n\tif strings.HasPrefix(err.Error(), \"failed to parse token\") {\n\t\t// malformed token: return 400, ask client to re-issue\n\t}\n}","preventionTips":["Emit tokens only with a maintained JWT/JWS library.","Never send opaque keys or session ids where a JWT is expected.","Beware proxies truncating large Authorization headers.","Use base64url (not standard base64) for all segments.","Add client-side pre-validation of token shape before sending."],"tags":["jwt","authentication","parsing","kbs"],"backgroundTag":"invalid-argument-format","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}