{"record":{"id":"7e18f29629d8265e","repo":"jwtk/jjwt","slug":"either-a-key-instance-or-a-kty-value-is-required-t","errorCode":null,"errorMessage":"Either a Key instance or a kty value is required to create a JWK.","messagePattern":"Either a Key instance or a kty value is required to create a JWK\\.","errorType":"exception","errorClass":"io.jsonwebtoken.security.InvalidKeyException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/DispatchingJwkFactory.java","lineNumber":77,"sourceCode":"\n    @Override\n    public JwkContext<Key> newContext(JwkContext<?> src, Key key) {\n        Assert.notNull(src, \"JwkContext cannot be null.\");\n        String kty = src.getType();\n        assertKeyOrKeyType(key, kty);\n        for (FamilyJwkFactory<Key, ?> factory : this.factories) {\n            if (factory.supports(key) || factory.supports(src)) {\n                JwkContext<Key> ctx = factory.newContext(src, key);\n                return Assert.notNull(ctx, \"FamilyJwkFactory implementation cannot return null JwkContexts.\");\n            }\n        }\n        throw noFamily(key, kty);\n    }\n\n    private static void assertKeyOrKeyType(Key key, String kty) {\n        if (key == null && !Strings.hasText(kty)) {\n            String msg = \"Either a Key instance or a \" + AbstractJwk.KTY + \" value is required to create a JWK.\";\n            throw new InvalidKeyException(msg);\n        }\n    }\n\n    @Override\n    public Jwk<Key> createJwk(JwkContext<Key> ctx) {\n\n        Assert.notNull(ctx, \"JwkContext cannot be null.\");\n\n        final Key key = ctx.getKey();\n        final String kty = Strings.clean(ctx.getType());\n        assertKeyOrKeyType(key, kty);\n\n        for (FamilyJwkFactory<Key, ?> factory : this.factories) {\n            if (factory.supports(ctx)) {\n                String algFamilyId = Assert.hasText(factory.getId(), \"factory id cannot be null or empty.\");\n                if (kty == null) {\n                    ctx.setType(algFamilyId); //ensure the kty is available for the rest of the creation process\n                }","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/DispatchingJwkFactory.java#L59-L95","documentation":"DispatchingJwkFactory.assertKeyOrKeyType enforces that to create a JWK you must supply either a java.security.Key instance or a kty (key type) value in the JwkContext. With neither, there is no way to select a family-specific JwkFactory, so it throws InvalidKeyException.","triggerScenarios":"Calling Jwks.builder() without .setKey(...) and without .setKty(...); building a JwkContext programmatically with an empty context and calling createJwk.","commonSituations":"Fluent Jwks.builder() chains where the developer forgot to set the key or kty; dynamic JWK creation where values are conditionally populated and both key and kty end up absent.","solutions":["Set a Key on the builder: Jwks.builder().setKey(key).build().","Or set the key type explicitly: Jwks.builder().setKty(\"RSA\").put(...).build().","Ensure context values are populated before calling createJwk when building contexts manually."],"exampleFix":"// before\nJwk jwk = Jwks.builder().put(\"n\", n).put(\"e\", e).build();\n// after\nJwk jwk = Jwks.builder().setKty(\"RSA\").put(\"n\", n).put(\"e\", e).build();","handlingStrategy":"validation","validationCode":"if (key == null && (kty == null || kty.trim().isEmpty())) {\n    throw new IllegalArgumentException(\"Provide either a Key or a kty value to build a JWK\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Jwk<?> jwk = Jwks.builder().setKey(key).build();\n} catch (io.jsonwebtoken.security.InvalidKeyException e) {\n    // set kty or key before building\n}","preventionTips":["Always call setKey(...) or setKty(...) on Jwks.builder()","When building contexts dynamically, assert required fields are populated before createJwk"],"tags":["java","jjwt","jwk","missing-argument"],"backgroundTag":"missing-required-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"}