jwtk/jjwt · error · io.jsonwebtoken.security.InvalidKeyException

Unrecognized Edwards Curve key

Error message

Unrecognized Edwards Curve key: [${key}]

What it means

EdwardsCurve.forKey identifies which Edwards curve (Ed25519, Ed448, X25519, X448) a key belongs to by inspecting its algorithm and encoded format. If findByKey cannot match the key to any known Edwards curve, this InvalidKeyException is thrown, since the key cannot be used for any Edwards-curve operation.

Solutions

  1. Ensure you pass an Ed25519/Ed448/X25519/X448 key generated via Jwts.SIG.keyPair() or a compatible JCE provider.
  2. Log KeysBridge.toString(key) (shown in the message) to see the key's algorithm/format and confirm it is an OKP key.
  3. Install a provider that supports Edwards curves (e.g. Java 15+ built-in or BouncyCastle) so keys have the expected algorithm names.
  4. Regenerate the key pair if it was produced by a non-standard implementation.

Example fix

// before: EC key used where an OKP key is required
KeyPair kp = KeyPairGenerator.getInstance("EC").generateKeyPair();
Jwts.builder().signWith(kp.getPrivate(), Jwts.SIG.EdDSA);
// after
KeyPair kp = Jwts.SIG.EdDSA.keyPair().build();
Jwts.builder().signWith(kp.getPrivate(), Jwts.SIG.EdDSA);
Defensive patterns

Strategy: type-guard

Validate before calling

EdwardsCurve curve = EdwardsCurve.findByKey(key);
if (curve == null) {
  throw new IllegalArgumentException("Not an Edwards curve key: " + key.getAlgorithm());
}

Type guard

boolean isEdwardsKey(java.security.Key k) {
  String a = k.getAlgorithm();
  return a.equals("Ed25519") || a.equals("Ed448") || a.equals("X25519") || a.equals("X448");
}

Try / catch

try {
  Jwts.builder().signWith(key, Jwts.SIG.EdDSA).compact();
} catch (InvalidKeyException e) {
  // unrecognized key: regenerate an OKP key pair
}

Prevention

When it happens

Trigger: Passing a non-Edwards key (RSA, EC, HMAC) to APIs expecting OKP keys — e.g. EdSignatureAlgorithm sign/verify, ECDH with OKP recipient — or an Edwards key whose encoded form is unrecognizable to the JVM provider.

Common situations: Using an EC P-256 key where an Ed25519 key is required; a key loaded from a provider that reports an unfamiliar algorithm name; a custom/foreign Key implementation that doesn't expose recognizable encoded bytes.

Related errors


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/512db51639ec4c21. Report an issue: GitHub.

Appendix: source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/EdwardsCurve.java:378

    }

    private static int findOidTerminalNode(byte[] encoded) {
        int index = Bytes.indexOf(encoded, ASN1_OID_PREFIX);
        if (index > -1) {
            index = index + ASN1_OID_PREFIX.length;
            if (index < encoded.length) {
                return encoded[index];
            }
        }
        return -1;
    }

    public static EdwardsCurve forKey(Key key) {
        Assert.notNull(key, "Key cannot be null.");
        EdwardsCurve curve = findByKey(key);
        if (curve == null) {
            String msg = "Unrecognized Edwards Curve key: [" + KeysBridge.toString(key) + "]";
            throw new InvalidKeyException(msg);
        }
        //TODO: assert key exists on discovered curve via equation
        return curve;
    }

    @SuppressWarnings("UnusedReturnValue")
    static <K extends Key> K assertEdwards(K key) {
        forKey(key); // will throw UnsupportedKeyException if the key is not an Edwards key
        return key;
    }
}

View on GitHub (pinned to fb71496164)