{"record":{"id":"de9869d859ef3b7b","repo":"jwtk/jjwt","slug":"jwk-must-be-a-map-string-json-object-type-fo","errorCode":null,"errorMessage":"JWK must be a Map<String,?> (JSON Object). Type found: ${type}.","messagePattern":"JWK must be a Map<String,\\?> \\(JSON Object\\)\\. Type found: (.+?)\\.","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/JwkConverter.java","lineNumber":134,"sourceCode":"    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());\n        if (val == null) {\n            String msg = \"JWK \" + param + \" value cannot be null.\";\n            throw new MalformedKeyException(msg);\n        }\n        if (!(val instanceof String)) {\n            String msg = \"JWK \" + param + \" value must be a String. Type found: \" + val.getClass().getName();\n            throw new MalformedKeyException(msg);","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/JwkConverter.java#L116-L152","documentation":"JwkConverter.convertFrom expects the raw parsed JSON value for a JWK to be a Map (JSON object), since JWKs are defined as JSON objects per RFC 7517. If the value is any other type (string, number, list, null), an IllegalArgumentException is thrown stating the actual Java type found.","triggerScenarios":"Parsing a JWT/JWKS where the `jwk` header value or a JWKS entry is not a JSON object — e.g. `\"jwk\": \"string\"`, a JSON array of keys passed where a single key object is expected, or deserializing nested structures that collapse to non-Map types.","commonSituations":"Hand-written tokens where the jwk header was serialized as a string instead of an object; JWKS documents whose `keys` array contains non-object entries; a producer library emitting a JWK wrapped in quotes; confusion between a JWK Set and a single JWK.","solutions":["Ensure the JWK value in the header/document is a JSON object like {\"kty\":\"EC\",...}, not a string or array.","If you meant to pass a JWK Set, use the appropriate JWKS parser API for `keys` arrays instead of single-JWK conversion.","Regenerate the token with a compliant producer; do not manually quote the JWK JSON.","Validate the JSON document shape before parsing (jwk must be an object)."],"exampleFix":"// before: JWK serialized as a string\n{\"jwk\": \"{\\\"kty\\\":\\\"EC\\\"...}\"}\n// after: JWK as a JSON object\n{\"jwk\": {\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"...\",\"y\":\"...\"}}","handlingStrategy":"type-guard","validationCode":"Object jwk = header.get(\"jwk\");\nif (!(jwk instanceof Map)) {\n  throw new IllegalArgumentException(\"jwk header must be a JSON object, got: \" + (jwk == null ? \"null\" : jwk.getClass().getName()));\n}","typeGuard":"boolean isJwkObject(Object o) {\n  return o instanceof Map && ((Map<?,?>)o).get(\"kty\") instanceof String;\n}","tryCatchPattern":"try {\n  Jwk<?> jwk = Jwks.parser().build().parse(json);\n} catch (IllegalArgumentException e) {\n  // JWK value was not a JSON object; fix producer output\n}","preventionTips":["Never serialize a JWK as a JSON string; keep it as an object","Validate JWKS documents: each entry in `keys` must be an object","Parse JWKS with the JWKS parser API, not the single-JWK API","Validate token header shapes with a schema before parsing"],"tags":["jwk","json","validation","type-mismatch"],"backgroundTag":"schema-validation-failed","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"}