{"record":{"id":"c4a76dc5527dcb66","repo":"OpenNHP/opennhp","slug":"invalid-x-coordinate-w","errorCode":null,"errorMessage":"invalid x coordinate: %w","messagePattern":"invalid x coordinate: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/server/kbs/resource/resource.go","lineNumber":237,"sourceCode":"\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\n\txBytes, err := base64.RawURLEncoding.DecodeString(xStr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid x coordinate: %w\", err)\n\t}\n\tyBytes, err := base64.RawURLEncoding.DecodeString(yStr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid y coordinate: %w\", err)\n\t}\n\n\tpublicKey := &ecdsa.PublicKey{\n\t\tCurve: elliptic.P256(),\n\t\tX:     new(big.Int).SetBytes(xBytes),\n\t\tY:     new(big.Int).SetBytes(yBytes),\n\t}\n\n\t// Now verify the token with the extracted public key\n\ttoken, err := jwt.Parse(tokenString, func(token *jwt.Token) (any, error) {\n\t\t// Check signing method\n\t\tif _, ok := token.Method.(*jwt.SigningMethodECDSA); !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected signing method: %v\", token.Header[\"alg\"])\n\t\t}","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/kbs/resource/resource.go#L219-L255","documentation":"The 'x' coordinate string must decode as unpadded base64url (RawURLEncoding); if decoding fails, VerifyJWT returns 'invalid x coordinate: %w' wrapping the base64 error. This catches wrong padding, illegal characters, or wrong encoding variant in the JWK coordinate.","triggerScenarios":"jwk.x uses standard base64 with '=' padding, contains '+' or '/' instead of '-' and '_', includes whitespace/newlines, or is otherwise not valid base64url. Reached during GetResource token verification.","commonSituations":"Client encodes coordinates with StdEncoding instead of RawURLEncoding; JWT header JSON was re-encoded with padded base64 by an intermediary; copy-paste introduced whitespace or line breaks.","solutions":["Encode JWK coordinates with base64.RawURLEncoding (unpadded URL-safe) on the client.","Strip whitespace/newlines from coordinate strings before embedding.","Check the wrapping base64 error in the log — illegal character vs padding tells you which variant was used.","If the producer emits padded base64, decode offline and re-encode unpadded, or fix at the source.","Regenerate the token with the reference client/library to guarantee correct encoding."],"exampleFix":"// before\nxB64 := base64.StdEncoding.EncodeToString(xBytes)\n// after\nxB64 := base64.RawURLEncoding.EncodeToString(xBytes)","handlingStrategy":"validation","validationCode":"func isRawURLB64(s string) bool {\n\t_, err := base64.RawURLEncoding.DecodeString(s)\n\treturn err == nil\n}\n// isRawURLB64(jwk[\"x\"].(string)) before calling VerifyJWT","typeGuard":null,"tryCatchPattern":"token, err := VerifyJWT(rawToken)\nif err != nil && strings.Contains(err.Error(), \"invalid x coordinate\") {\n\t// bad encoding from client: return 401 and log the base64 cause\n}","preventionTips":["Always use base64.RawURLEncoding for JWK members.","Strip whitespace/newlines from coordinates.","Never mix StdEncoding and RawURLEncoding in one header.","Validate tokens locally before sending.","Prefer library-generated headers over manual assembly."],"tags":["jwt","base64","encoding","jwk"],"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"}