jwtk/jjwt · error · MalformedKeyException

RSA JWK 'oth' (Other Prime Info) element cannot be null.

Error message

RSA JWK 'oth' (Other Prime Info) element cannot be null.

What it means

When converting an RSA JWK's 'oth' (Other Prime Info) array back into a java.security.spec.RSAOtherPrimeInfo, each element must be a non-null map of name/value pairs (r, d, t). A null element is rejected with MalformedKeyException.

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/RSAOtherPrimeInfoConverter.java:53

    static final Parameter<BigInteger> PRIME_FACTOR = Parameters.secretBigInt("r", "Prime Factor");
    static final Parameter<BigInteger> FACTOR_CRT_EXPONENT = Parameters.secretBigInt("d", "Factor CRT Exponent");
    static final Parameter<BigInteger> FACTOR_CRT_COEFFICIENT = Parameters.secretBigInt("t", "Factor CRT Coefficient");
    static final Set<Parameter<?>> PARAMS = Collections.<Parameter<?>>setOf(PRIME_FACTOR, FACTOR_CRT_EXPONENT, FACTOR_CRT_COEFFICIENT);

    @Override
    public Object applyTo(RSAOtherPrimeInfo info) {
        Map<String, Object> m = new LinkedHashMap<>(3);
        m.put(PRIME_FACTOR.getId(), PRIME_FACTOR.applyTo(info.getPrime()));
        m.put(FACTOR_CRT_EXPONENT.getId(), FACTOR_CRT_EXPONENT.applyTo(info.getExponent()));
        m.put(FACTOR_CRT_COEFFICIENT.getId(), FACTOR_CRT_COEFFICIENT.applyTo(info.getCrtCoefficient()));
        return m;
    }

    @Override
    public RSAOtherPrimeInfo applyFrom(Object o) {
        if (o == null) {
            throw new MalformedKeyException("RSA JWK 'oth' (Other Prime Info) element cannot be null.");
        }
        if (!(o instanceof Map)) {
            String msg = "RSA JWK 'oth' (Other Prime Info) must contain map elements of name/value pairs. " +
                    "Element type found: " + o.getClass().getName();
            throw new MalformedKeyException(msg);
        }
        Map<?, ?> m = (Map<?, ?>) o;
        if (Collections.isEmpty(m)) {
            throw new MalformedKeyException("RSA JWK 'oth' (Other Prime Info) element map cannot be empty.");
        }

        // Need a Context instance to satisfy the API contract of the reader.get* methods below.
        JwkContext<?> ctx = new DefaultJwkContext<>(PARAMS);
        try {
            for (Map.Entry<?, ?> entry : m.entrySet()) {
                String name = String.valueOf(entry.getKey());
                ctx.put(name, entry.getValue());
            }

View on GitHub (pinned to fb71496164)

Solutions

  1. Remove null entries from the 'oth' array, or omit 'oth' entirely for standard two-prime RSA keys.
  2. Sanitize/validate the JWK JSON before parsing, rejecting null array elements.
  3. Catch MalformedKeyException when ingesting external JWKs and treat the key as invalid.

Example fix

// before
{"kty":"RSA","oth":[null]}
// after
{"kty":"RSA"}  // or a fully populated oth element
{"kty":"RSA","oth":[{"r":"...","d":"...","t":"..."}]}
Defensive patterns

Strategy: validation

Validate before calling

List<Object> oth = jwk.get("oth", List.class);
if (oth != null) {
    oth.forEach(e -> Objects.requireNonNull(e, "oth element must not be null"));
}

Type guard

boolean validOth(List<Object> oth) {
    return oth == null || oth.stream().allMatch(e -> e instanceof Map && e != null);
}

Try / catch

try {
    RsaJwk jwk = Jwks.parser().build().parse(json);
} catch (MalformedKeyException e) {
    // malformed oth (or other) JWK field
}

Prevention

When it happens

Trigger: Parsing an RSA JWK whose 'oth' array contains a JSON null element, e.g. {"oth":[null]} or building a JWK with a null entry in the oth collection.

Common situations: Hand-edited or third-party-generated JWKs with null placeholders; serializers emitting nulls for missing primes instead of omitting the 'oth' parameter.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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