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
- Pass the underlying key via providerKey.getKey() instead of the ProviderKey itself.
- Skip wrapping if key instanceof ProviderKey, reusing the existing wrapper.
- 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
- Unwrap ProviderKey instances before re-wrapping
- Avoid wrapping keys returned by provider-backed operations
- Track key provenance to prevent double wrapping
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
- ${Class} callback execution failed: ${t.getMessage()}
- Unable to compute ${getId()} signature with JCA algorithm '$
- Invalid AES key length: ${bitsMsg(keyBitLength)}. AES only s
- Unrecognized OKP JWK ${param} value '${crvId}'
- Specified Edwards Curve PublicKey does not match the specifi
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/20a35ce7aff2fa59.
Report an issue: GitHub.