{"record":{"id":"d495b463d411d87e","repo":"ory/hydra","slug":"failed-to-encode-json-web-key-set","errorCode":null,"errorMessage":"failed to encode JSON Web Key Set","messagePattern":"failed to encode JSON Web Key Set","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/jwk_sdk.go","lineNumber":23,"sourceCode":"\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\n\tjose \"github.com/go-jose/go-jose/v3\"\n\t\"github.com/pkg/errors\"\n\n\thydra \"github.com/ory/hydra-client-go/v2\"\n)\n\n// OnlyPublicSDKKeys strips the private parts from a key set so that it is safe\n// to print.\nfunc OnlyPublicSDKKeys(in []hydra.JsonWebKey) (out []hydra.JsonWebKey, _ error) {\n\tvar interim []jose.JSONWebKey\n\tvar b bytes.Buffer\n\n\tif err := json.NewEncoder(&b).Encode(&in); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to encode JSON Web Key Set\")\n\t}\n\n\tif err := json.NewDecoder(&b).Decode(&interim); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to decode JSON Web Key Set\")\n\t}\n\n\tfor i, key := range interim {\n\t\tinterim[i] = key.Public()\n\t}\n\n\tb.Reset()\n\tif err := json.NewEncoder(&b).Encode(&interim); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to encode JSON Web Key Set\")\n\t}\n\n\tvar keys []hydra.JsonWebKey\n\tif err := json.NewDecoder(&b).Decode(&keys); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to decode JSON Web Key Set\")","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/cmd/jwk_sdk.go#L5-L41","documentation":"OnlyPublicSDKKeys converts a set of Hydra JSON Web Keys to their public form by round-tripping them through encoding/json. This first-wrap error occurs when json.Encoder fails to serialize the incoming []hydra.JsonWebKey set — practically never happens for valid keys since JsonWebKey is JSON-marshalable, but the library wraps it defensively.","triggerScenarios":"Calling OnlyPublicSDKKeys with a []hydra.JsonWebKey whose contents cannot be JSON-encoded — e.g. keys containing unsupported values that the jose-backed JsonWebKey marshals to invalid JSON (rare; corrupt or programmatically-constructed key structs).","commonSituations":"Passing keys constructed manually with non-serializable fields instead of keys obtained from hydra's JWK API; a JsonWebKey carrying exotic (e.g. NaN float or channel-backed custom marshaling) data from an interceptor.","solutions":["Ensure the []hydra.JsonWebKey input comes from the hydra JWK admin/API response (jose.JSONWebKeySet), not hand-built structs.","Test-encode one key with json.Marshal(key) to find the offending key and inspect its fields.","Filter out malformed keys before calling OnlyPublicSDKKeys."],"exampleFix":"// before\nout, err := OnlyPublicSDKKeys(handBuiltKeys) // corrupt key -> encode fails\n\n// after\nvalid := keys[:0]\nfor _, k := range keys {\n    if _, err := json.Marshal(k); err == nil {\n        valid = append(valid, k)\n    }\n}\nout, err := OnlyPublicSDKKeys(valid)","handlingStrategy":"validation","validationCode":"for _, k := range in {\n    if _, err := json.Marshal(k); err != nil {\n        return fmt.Errorf(\"key %q is not JSON-marshalable: %w\", k.Kid, err)\n    }\n}","typeGuard":"func isMarshalableJWK(k hydra.JsonWebKey) bool {\n    b, err := json.Marshal(k)\n    return err == nil && len(b) > 0\n}","tryCatchPattern":"out, err := OnlyPublicSDKKeys(keys)\nif err != nil {\n    return nil, fmt.Errorf(\"converting SDK keys failed: %+v\", err) // %+v reveals wrapped json cause\n}","preventionTips":["Only feed keys obtained from hydra's JWK API or jwk.Create into this converter.","Avoid hand-building JsonWebKey structs with custom/private fields.","Keep hydra client and go-jose versions aligned in go.mod."],"tags":["jwk","json","serialization","sdk"],"backgroundTag":"json-serialization-failed","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}