{"record":{"id":"72ebca78c2d99707","repo":"ory/hydra","slug":"unsupported-private-public-key-pairs-t-t","errorCode":null,"errorMessage":"unsupported private / public key pairs: %T, %T","messagePattern":"unsupported private / public key pairs: %T, %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fosite/token/jwt/jwt.go","lineNumber":75,"sourceCode":"\t\treturn generateToken(claims, header, jose.ES256, t)\n\tcase jose.OpaqueSigner:\n\t\tswitch tt := t.Public().Key.(type) {\n\t\tcase *rsa.PrivateKey:\n\t\t\talg := jose.RS256\n\t\t\tif len(t.Algs()) > 0 {\n\t\t\t\talg = t.Algs()[0]\n\t\t\t}\n\n\t\t\treturn generateToken(claims, header, alg, t)\n\t\tcase *ecdsa.PrivateKey:\n\t\t\talg := jose.ES256\n\t\t\tif len(t.Algs()) > 0 {\n\t\t\t\talg = t.Algs()[0]\n\t\t\t}\n\n\t\t\treturn generateToken(claims, header, alg, t)\n\t\tdefault:\n\t\t\treturn \"\", \"\", errors.Errorf(\"unsupported private / public key pairs: %T, %T\", t, tt)\n\t\t}\n\tdefault:\n\t\treturn \"\", \"\", errors.Errorf(\"unsupported private key type: %T\", t)\n\t}\n}\n\n// Validate validates a token and returns its signature or an error if the token is not valid.\nfunc (j *DefaultSigner) Validate(ctx context.Context, token string) (string, error) {\n\tkey, err := j.GetPrivateKey(ctx)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif t, ok := key.(*jose.JSONWebKey); ok {\n\t\tkey = t.Key\n\t}\n\n\tswitch t := key.(type) {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/fosite/token/jwt/jwt.go#L57-L93","documentation":"jwt.DefaultSigner.Generate only supports known private key types: ECDSA (ECPrivateKey), RSA (RSAPrivateKey), ed25519 (Ed25519PrivateKey) and their *jose.JSONWebKey/e.JWK wrappers. Falling into the key-pair 'default' branch means the key pair type (the second %T) is not one of these, so no token can be signed.","triggerScenarios":"Calling Generate (public) with a key pair whose underlying key type is unsupported — e.g. a custom signer exposing a *jose.JSONWebKey whose embedded key is an unsupported algorithm/key type, or passing a pointer-wrapper/PEM string instead of a parsed private key.","commonSituations":"Loading keys with a parser that yields an unexpected type (e.g. PKCS#1 parsed into interface{}, opaque crypto.Signer wrappers, HSM keys); swapping key providers (KMS, vault) without adapting to jose JSONWebKey; typos when constructing the signer's key interface.","solutions":["Provide a supported key type: *ecdsa.PrivateKey, *rsa.PrivateKey, ed25519.PrivateKey, or a *jose.JSONWebKey wrapping one of them","Parse PEM/DER into the concrete Go key type before passing it to the signer (e.g. x509.ParseECPrivateKey / ParsePKCS8PrivateKey with type switch)","If keys come from a KMS/HSM, wrap them in a type the signer understands or implement your own Signer interface","Log the key's %T at startup to confirm which type is actually configured"],"exampleFix":"// before\nsigner := jwt.NewSignerRS256(\"key-id\", pemBytes) // raw bytes, wrong type\n// after\nblock, _ := pem.Decode(pemBytes)\nkey, err := x509.ParsePKCS8PrivateKey(block.Bytes)\nrsaKey, ok := key.(*rsa.PrivateKey)\nif !ok { return errors.New(\"expected RSA private key\") }\nsigner := jwt.NewSignerRS256(\"key-id\", rsaKey)","handlingStrategy":"type-guard","validationCode":"func assertSignableKey(k interface{}) error {\n    switch t := k.(type) {\n    case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey, *jose.JSONWebKey, *jwt.ECDSAKeyPair, *jwt.RSAKeyPair, *jwt.Ed25519KeyPair:\n        return nil\n    default:\n        return fmt.Errorf(\"unsupported signing key type %T\", k)\n    }\n}","typeGuard":"func isSupportedJWTKey(k interface{}) bool {\n    switch k.(type) {\n    case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey, *jose.JSONWebKey,\n         *jwt.ECDSAKeyPair, *jwt.RSAKeyPair, *jwt.Ed25519KeyPair:\n        return true\n    }\n    return false\n}","tryCatchPattern":"token, sig, err := signer.Generate(ctx, claims, header)\nif err != nil && strings.Contains(err.Error(), \"unsupported private\") {\n    log.Fatalf(\"signing key misconfigured: %v\", err)\n}","preventionTips":["Parse PEM/DER into concrete Go key types before configuring the signer","Avoid opaque crypto.Signer or KMS handles unless wrapped in a supported type","Log the key type at startup when loading signing material","Keep signer key wiring and key storage in one module so types stay consistent"],"tags":["jwt","fosite","signing-keys","unsupported-key-type"],"backgroundTag":"unsupported-jwt-signing-key","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"}