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, err

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Use one of the supported algorithms: ES256, ES384, ES512, EdDSA, RS256, RS384, RS512, PS256, PS384, PS512
  2. If you need HMAC (HS*), generate a []byte secret yourself instead of calling NewSigningKey
  3. 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

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


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/91cbfb0e7dd8eabb. Report an issue: GitHub.