jwtk/jjwt · error · UnsupportedKeyException

Unrecognized JWA EC curve id '${jwaCurveId}'

Error message

Unrecognized JWA EC curve id '${jwaCurveId}'

What it means

JJWT looks up an ECCurve enum instance by the JWA curve id (e.g. 'P-256', 'P-384', 'P-521', 'secp256k1') when building or parsing an EC JWK. If the id does not match any known curve, an UnsupportedKeyException is thrown. This means the key material references a curve the library does not recognize.

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/AbstractEcJwkFactory.java:37

import io.jsonwebtoken.impl.lang.Converters;
import io.jsonwebtoken.impl.lang.Parameter;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Jwk;
import io.jsonwebtoken.security.UnsupportedKeyException;

import java.math.BigInteger;
import java.security.Key;
import java.security.interfaces.ECKey;
import java.security.spec.EllipticCurve;
import java.util.Set;

abstract class AbstractEcJwkFactory<K extends Key & ECKey, J extends Jwk<K>> extends AbstractFamilyJwkFactory<K, J> {

    protected static ECCurve getCurveByJwaId(String jwaCurveId) {
        ECCurve curve = ECCurve.findById(jwaCurveId);
        if (curve == null) {
            String msg = "Unrecognized JWA EC curve id '" + jwaCurveId + "'";
            throw new UnsupportedKeyException(msg);
        }
        return curve;
    }

    /**
     * https://tools.ietf.org/html/rfc7518#section-6.2.1.2 indicates that this algorithm logic is defined in
     * http://www.secg.org/sec1-v2.pdf Section 2.3.5.
     *
     * @param curve      EllipticCurve
     * @param coordinate EC point coordinate (e.g. x or y) on the {@code curve}
     * @return A base64Url-encoded String representing the EC field element per the RFC format
     */
    // Algorithm defined in http://www.secg.org/sec1-v2.pdf Section 2.3.5
    static String toOctetString(EllipticCurve curve, BigInteger coordinate) {
        byte[] bytes = Converters.BIGINT_UBYTES.applyTo(coordinate);
        int fieldSizeInBits = curve.getField().getFieldSize();
        int mlen = Bytes.length(fieldSizeInBits);
        bytes = Bytes.prepad(bytes, mlen);

View on GitHub (pinned to fb71496164)

Solutions

  1. Use a JWA-standard curve id exactly: P-256, P-384, P-521, or secp256k1 (if supported).
  2. Regenerate the key with a supported curve, e.g. KeyPairGenerator.getInstance('EC') initialized with ECGenParameterSpec('secp256r1').
  3. Upgrade JJWT to a version that supports your curve.
  4. Normalize case before passing the curve id.

Example fix

// before
jwk.put("crv", "p256");
// after
jwk.put("crv", "P-256");
Defensive patterns

Strategy: validation

Validate before calling

boolean supported = jwk.getString("crv").matches("P-(256|384|521)|secp256k1");
if (!supported) throw new IllegalArgumentException("Unsupported EC curve: " + jwk.getString("crv"));

Type guard

boolean isSupportedCurve(String crv) { return "P-256".equals(crv) || "P-384".equals(crv) || "P-521".equals(crv) || "secp256k1".equals(crv); }

Try / catch

try { curve = getCurveByJwaId(crv); }
catch (UnsupportedKeyException e) { log.error("Unsupported curve {}", crv); return Result.unsupported(e); }

Prevention

When it happens

Trigger: Parsing or creating an EC JWK whose 'crv' member is misspelled, omitted variants, or a curve unsupported by the JJWT version (e.g. 'secp256k1' on versions lacking Ed/EC secp support, or lowercase 'p-256').

Common situations: Hand-written JWK JSON with a wrong crv value; keys generated with an exotic curve then fed to JJWT; older JJWT versions used against newer key sets; case-sensitivity mistakes.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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