{"record":{"id":"20a35ce7aff2fa59","repo":"jwtk/jjwt","slug":"nesting-not-permitted","errorCode":null,"errorMessage":"Nesting not permitted.","messagePattern":"Nesting not permitted\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/ProviderKey.java","lineNumber":48,"sourceCode":"    public static Provider getProvider(Key key, Provider backup) {\n        if (key instanceof ProviderKey<?>) {\n            ProviderKey<?> pkey = (ProviderKey<?>) key;\n            return Assert.stateNotNull(pkey.getProvider(), \"ProviderKey provider can never be null.\");\n        }\n        return backup;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public static <K extends Key> K getKey(K key) {\n        return key instanceof ProviderKey ? ((ProviderKey<K>) key).getKey() : key;\n    }\n\n    ProviderKey(Provider provider, T key) {\n        this.provider = Assert.notNull(provider, \"Provider cannot be null.\");\n        this.key = Assert.notNull(key, \"Key argument cannot be null.\");\n        if (key instanceof ProviderKey<?>) {\n            String msg = \"Nesting not permitted.\";\n            throw new IllegalArgumentException(msg);\n        }\n    }\n\n    @Override\n    public T getKey() {\n        return this.key;\n    }\n\n    @Override\n    public String getAlgorithm() {\n        return this.key.getAlgorithm();\n    }\n\n    @Override\n    public String getFormat() {\n        return this.key.getFormat();\n    }\n","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/ProviderKey.java#L30-L66","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nProviderKey pk = new ProviderKey(provider, alreadyWrappedKey);\n// after\nKey inner = (alreadyWrappedKey instanceof ProviderKey<?>)\n    ? ((ProviderKey<?>) alreadyWrappedKey).getKey() : alreadyWrappedKey;\nProviderKey pk = new ProviderKey(provider, inner);","handlingStrategy":"validation","validationCode":"if (key instanceof ProviderKey<?>) {\n    key = ((ProviderKey<?>) key).getKey(); // unwrap first\n}","typeGuard":"Key unwrap(Key k) { return k instanceof ProviderKey<?> pk ? pk.getKey() : k; }","tryCatchPattern":"try {\n    ProviderKey pk = new ProviderKey(provider, key);\n} catch (IllegalArgumentException e) {\n    // key already wrapped: unwrap and retry\n}","preventionTips":["Unwrap ProviderKey instances before re-wrapping","Avoid wrapping keys returned by provider-backed operations","Track key provenance to prevent double wrapping"],"tags":["keys","crypto","provider"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}