jwtk/jjwt · error · IllegalArgumentException

Nesting not permitted.

Error message

Nesting not permitted.

What it means

ProviderKey wraps a Key with a JCA Provider. Nesting a ProviderKey inside another ProviderKey is rejected in the constructor with IllegalArgumentException because double-wrapping serves no purpose and would hide the original provider association.

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/ProviderKey.java:48

    public static Provider getProvider(Key key, Provider backup) {
        if (key instanceof ProviderKey<?>) {
            ProviderKey<?> pkey = (ProviderKey<?>) key;
            return Assert.stateNotNull(pkey.getProvider(), "ProviderKey provider can never be null.");
        }
        return backup;
    }

    @SuppressWarnings("unchecked")
    public static <K extends Key> K getKey(K key) {
        return key instanceof ProviderKey ? ((ProviderKey<K>) key).getKey() : key;
    }

    ProviderKey(Provider provider, T key) {
        this.provider = Assert.notNull(provider, "Provider cannot be null.");
        this.key = Assert.notNull(key, "Key argument cannot be null.");
        if (key instanceof ProviderKey<?>) {
            String msg = "Nesting not permitted.";
            throw new IllegalArgumentException(msg);
        }
    }

    @Override
    public T getKey() {
        return this.key;
    }

    @Override
    public String getAlgorithm() {
        return this.key.getAlgorithm();
    }

    @Override
    public String getFormat() {
        return this.key.getFormat();
    }

View on GitHub (pinned to fb71496164)

Solutions

  1. Pass the underlying key via providerKey.getKey() instead of the ProviderKey itself.
  2. Skip wrapping if key instanceof ProviderKey, reusing the existing wrapper.
  3. Check the key type before constructing to avoid double wrapping.

Example fix

// before
ProviderKey pk = new ProviderKey(provider, alreadyWrappedKey);
// after
Key inner = (alreadyWrappedKey instanceof ProviderKey<?>)
    ? ((ProviderKey<?>) alreadyWrappedKey).getKey() : alreadyWrappedKey;
ProviderKey pk = new ProviderKey(provider, inner);
Defensive patterns

Strategy: validation

Validate before calling

if (key instanceof ProviderKey<?>) {
    key = ((ProviderKey<?>) key).getKey(); // unwrap first
}

Type guard

Key unwrap(Key k) { return k instanceof ProviderKey<?> pk ? pk.getKey() : k; }

Try / catch

try {
    ProviderKey pk = new ProviderKey(provider, key);
} catch (IllegalArgumentException e) {
    // key already wrapped: unwrap and retry
}

Prevention

When it happens

Trigger: Constructing new ProviderKey(provider, existingProviderKey) — i.e. passing a key that is itself a ProviderKey instance (e.g. wrapping an already-wrapped key from a previous operation).

Common situations: Re-wrapping keys returned by JJWT crypto operations that already carry a provider; generic key-wrapping utility code applied twice; chaining wrappers after key transformation steps.

Related errors


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