{"record":{"id":"435e7379ccf71d67","repo":"jwtk/jjwt","slug":"value-must-be-articlefor-desired-desired-n","errorCode":null,"errorMessage":"Value must be ${articleFor(desired)} ${desired}, not ${articleFor(jwkType)} ${jwkType}.","messagePattern":"Value must be (.+?) (.+?), not (.+?) (.+?)\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/JwkConverter.java","lineNumber":127,"sourceCode":"        } else if (PrivateJwk.class.isAssignableFrom(clazz)) {\n            nespace(sb).append(\"Private\");\n        }\n        nespace(sb).append(\"JWK\");\n        return sb.toString();\n    }\n\n    private IllegalArgumentException unexpectedIAE(Jwk<?> jwk) {\n        String desired = typeString(this.desiredType);\n        String jwkType = typeString(jwk);\n        String msg = \"Value must be \" + articleFor(desired) + \" \" + desired + \", not \" +\n                articleFor(jwkType) + \" \" + jwkType + \".\";\n        return new IllegalArgumentException(msg);\n    }\n\n    @Override\n    public T applyFrom(Object o) {\n        Assert.notNull(o, \"JWK cannot be null.\");\n        if (desiredType.isInstance(o)) {\n            return desiredType.cast(o);\n        } else if (o instanceof Jwk<?>) {\n            throw unexpectedIAE((Jwk<?>) o);\n        }\n        if (!(o instanceof Map)) {\n            String msg = \"JWK must be a Map<String,?> (JSON Object). Type found: \" + o.getClass().getName() + \".\";\n            throw new IllegalArgumentException(msg);\n        }\n        final Map<?, ?> map = Collections.immutable((Map<?, ?>) o);\n\n        Parameter<String> param = AbstractJwk.KTY;\n        // mandatory for all JWKs: https://datatracker.ietf.org/doc/html/rfc7517#section-4.1\n        // no need for builder param type conversion overhead if this isn't present:\n        if (Collections.isEmpty(map) || !map.containsKey(param.getId())) {\n            String msg = \"JWK is missing required \" + param + \" parameter.\";\n            throw new MalformedKeyException(msg);\n        }\n        Object val = map.get(param.getId());","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/JwkConverter.java#L109-L145","documentation":"This IllegalArgumentException is thrown by JwkConverter.applyFrom when a caller supplies a Jwk object instance, but it is not of the converter's desired type (e.g. the converter expects a PublicJwk but receives a PrivateJwk or SecretJwk). JwkConverter is used internally when parsing JWKs (e.g. for JWK Set members or key material in JWT headers), and the desired type enforces constraints like 'only public keys allowed'. The message names both the expected type and the actual JWK type so you can see exactly which kind of JWK was rejected.","triggerScenarios":"Calling applyFrom (directly or via parsing APIs like JwkSet parsing, or a Parser<PublicJwk<?>>) and passing an already-constructed Jwk instance whose concrete type (SecretJwk, RsaPrivateJwk, EcPrivateJwk, OctetPrivateJwk, etc.) does not match the converter's desiredType (e.g. PUBLIC_JWK converter receiving a private or secret Jwk). Hit at JwkConverter.java:127-131 where `o instanceof Jwk<?>` but `!desiredType.isInstance(o)`.","commonSituations":"Passing a private key JWK where the API only accepts public keys (e.g. embedding a JWK in a JWT header or JWE recipient, which requires public keys); confusing a SecretJwk (symmetric key) with an RSA/EC public key; using a converter instantiated for PublicJwk on data from a JWKS that contains private keys; refactors that changed the JWK kind (private -> public or vice versa) without updating the parser/decoder type.","solutions":["Check the message: the 'not a ...' part names the actual JWK type and the 'must be' part names the required type; convert your data to the required kind (e.g. derive the public JWK from the private Jwk via its `toPublicJwk()`-style accessor or `Keys`/builder utilities) before passing it.","If you have the JWK as a Map, remove the private-only parameters (\"d\", \"p\", \"q\", \"dp\", \"dq\", \"qi\") so it parses as a public JWK.","If you actually need to accept private/secret JWKs, use a converter/parser typed for Jwk or the appropriate private Jwk interface (e.g. JwkConverter.ANY) instead of the PublicJwk-typed one.","Verify you are not accidentally passing a Jwk object where a Map (raw JSON JWK) or Key object was expected; if the value is already the right Jwk, pass the underlying Key instead if the API accepts keys."],"exampleFix":"// before (private JWK passed where public is required)\nEcPrivateJwk priv = ...;\nparser.parse(priv); // Value must be an EC Public JWK, not an EC Private JWK.\n\n// after\nEcPublicJwk pub = priv.toPublicJwk();\nparser.parse(pub);","handlingStrategy":"type-guard","validationCode":"if (jwk instanceof PublicJwk) {\n    parser.parse(jwk); // safe\n} else if (jwk instanceof PrivateJwk) {\n    parser.parse(((EcPrivateJwk) jwk).toPublicJwk());\n}","typeGuard":"boolean isUsableForPublicContext(Jwk<?> jwk) {\n    return jwk instanceof PublicJwk;\n}","tryCatchPattern":"try {\n    T jwk = converter.applyFrom(value);\n} catch (IllegalArgumentException e) {\n    // message states required vs actual JWK type; convert or reject\n    throw new IllegalArgumentException(\"Unsupported JWK kind for this context: \" + e.getMessage(), e);\n}","preventionTips":["Keep private and public JWKs in separate variables/types so the compiler flags misuse.","Convert private JWKs to public form at the boundary where you publish or embed them.","Never embed SecretJwk or private JWKs in JWT headers or shared JWKS documents.","Prefer parsing from raw JSON Maps only when you control the source and know which key kind it contains."],"tags":["java","jjwt","jwk","type-mismatch","key-parsing"],"backgroundTag":"type-mismatch","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"}