ory/hydra · error
unknown algorithm %s for signing key
Error message
unknown algorithm %s for signing key
What it means
NewSigningKey generates a keypair only for the JOSE signature algorithms it knows: ES256/384/512, EdDSA, RS256/384/512, PS256/384/512. Passing any other jose.SignatureAlgorithm falls into the default branch and returns this error instead of a key.
Source
Thrown at oryx/josex/generate.go:82
}
return key.Public(), key, err
case jose.ES512:
key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
if err != nil {
return nil, nil, err
}
return key.Public(), key, err
case jose.EdDSA:
pub, key, err := ed25519.GenerateKey(rand.Reader)
return pub, key, err
case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
key, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, nil, err
}
return key.Public(), key, err
default:
return nil, nil, fmt.Errorf("unknown algorithm %s for signing key", alg)
}
}
// NewEncryptionKey generates a keypair for corresponding KeyAlgorithm.
func NewEncryptionKey(alg jose.KeyAlgorithm, bits int) (crypto.PublicKey, crypto.PrivateKey, error) {
switch alg {
case jose.RSA1_5, jose.RSA_OAEP, jose.RSA_OAEP_256:
if bits == 0 {
bits = 2048
}
if bits < 2048 {
return nil, nil, errors.New("invalid key size for RSA key, 2048 or more is required")
}
key, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, nil, err
}
return key.Public(), key, errView on GitHub (pinned to 4174065ffb)
Solutions
- Use one of the supported algorithms: ES256, ES384, ES512, EdDSA, RS256, RS384, RS512, PS256, PS384, PS512
- If you need HMAC (HS*), generate a []byte secret yourself instead of calling NewSigningKey
- Validate the alg value from config against the supported list before calling NewSigningKey and fail with a clear config error
Example fix
// before
key, priv, err := josex.NewSigningKey(jose.SignatureAlgorithm("HS256"), 0)
// after
key, priv, err := josex.NewSigningKey(jose.ES256, 0) Defensive patterns
Strategy: validation
Validate before calling
var supportedSigningAlgs = map[jose.SignatureAlgorithm]bool{
jose.ES256: true, jose.ES384: true, jose.ES512: true, jose.EdDSA: true,
jose.RS256: true, jose.RS384: true, jose.RS512: true,
jose.PS256: true, jose.PS384: true, jose.PS512: true,
}
func checkSigningAlg(alg jose.SignatureAlgorithm) error {
if !supportedSigningAlgs[alg] {
return fmt.Errorf("alg %q not supported for key generation", alg)
}
return nil
} Type guard
func isAsymmetricSigningAlg(alg string) bool {
switch alg {
case "ES256", "ES384", "ES512", "EdDSA", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512":
return true
}
return false
} Try / catch
pub, priv, err := josex.NewSigningKey(alg, bits)
if err != nil {
return fmt.Errorf("config error: cannot generate signing key: %w", err)
} Prevention
- Keep a whitelist of allowed algs in config parsing and validate at startup
- Never configure HS* algorithms for keypair generation — use raw secrets for HMAC
- Use go-jose constants (jose.ES256 etc.) instead of raw strings
- Add a unit test that generates a key for every alg your product claims to support
When it happens
Trigger: Calling josex.NewSigningKey with an algorithm such as HS256 (symmetric, unsupported here), a typo like "ES512K", or an encryption-only algorithm like RSA-OAEP-256; also via GenerateJWK or tests like assertCreateVerifiableCredential configured with such an alg.
Common situations: Config files where a signing alg was set to HMAC (HS*) which requires a shared secret, not a generated keypair; copying an encryption alg into the signing config; string algorithms that do not match go-jose constants.
Related errors
- unknown algorithm %s for encryption key
- invalid elliptic curve key size, this algorithm does not sup
- invalid key size for RSA key, 2048 or more is required
- invalid elliptic curve key size, use one of 256, 384, or 521
- invalid JWK key
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/91cbfb0e7dd8eabb.
Report an issue: GitHub.