{"record":{"id":"ebee92a91010b11c","repo":"OpenNHP/opennhp","slug":"invalid-y-coordinate-w","errorCode":null,"errorMessage":"invalid y coordinate: %w","messagePattern":"invalid y coordinate: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/server/kbs/resource/resource.go","lineNumber":241,"sourceCode":"\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}\n\t\treturn publicKey, nil\n\t})\n\n\tif err != nil {","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/kbs/resource/resource.go#L223-L259","documentation":"Identical check for the 'y' coordinate: it must decode as unpadded base64url, otherwise VerifyJWT returns 'invalid y coordinate: %w'. x may decode fine while y fails if the two were encoded by different code paths.","triggerScenarios":"jwk.y is padded base64, contains illegal base64url characters, or includes whitespace. Reached after x decoded successfully during GetResource token verification.","commonSituations":"Mixed encoders in client code (x fixed, y still using StdEncoding); external tool re-encoding the header with padding; manual token assembly pasting coordinates from a padded-base64 output.","solutions":["Encode 'y' with base64.RawURLEncoding on the client, matching 'x'.","Normalize: trim whitespace and convert '+'/'/' to '-'/'_', remove '=' padding.","Read the wrapped base64 error to identify padding vs character issues.","Audit client code for a second encoding path used for y.","Regenerate the token with a maintained library."],"exampleFix":"// before\nyB64 := base64.URLEncoding.EncodeToString(yBytes) // adds padding\n// after\nyB64 := base64.RawURLEncoding.EncodeToString(yBytes)","handlingStrategy":"validation","validationCode":"func coordsDecode(jwk map[string]any) bool {\n\tx, _ := jwk[\"x\"].(string); y, _ := jwk[\"y\"].(string)\n\t_, xe := base64.RawURLEncoding.DecodeString(x)\n\t_, ye := base64.RawURLEncoding.DecodeString(y)\n\treturn xe == nil && ye == nil\n}","typeGuard":null,"tryCatchPattern":"token, err := VerifyJWT(rawToken)\nif err != nil && strings.Contains(err.Error(), \"invalid y coordinate\") {\n\t// fix client encoding of y; return 401\n}","preventionTips":["Encode x and y with the same encoder in one helper.","Trim all whitespace before encoding.","Audit re-encoding intermediaries for added padding.","Round-trip test coordinates in client unit tests.","Regenerate tokens with a maintained library when unsure."],"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"}