FasterXML/jackson-databind · error · IllegalArgumentException

Cannot construct EnumMap; generic (key) type not available

Error message

Cannot construct EnumMap; generic (key) type not available

What it means

Thrown when constructing a deserializer for an EnumMap whose key type cannot be resolved to a concrete enum. Because of generic erasure, Jackson needs the key's enum class at build time; if only a raw EnumMap or a non-enum key is visible, it cannot wire the EnumMapDeserializer.

Source

Thrown at src/main/java/tools/jackson/databind/deser/BasicDeserializerFactory.java:925

            Class<?> mapClass = type.getRawClass();
            // [databind#1853]: Map `Map<ENUM,x>` to `EnumMap<ENUM,x>`
            if ((mapClass == Map.class) && keyType.isEnumType()) {
                mapClass = EnumMap.class;
                type = (MapType) config.getTypeFactory().constructSpecializedType(type, mapClass);
//                type = (MapType) config.getTypeFactory().constructMapType(mapClass, keyType, contentType);
            }
            if (EnumMap.class.isAssignableFrom(mapClass)) {
                ValueInstantiator inst;

                // 06-Mar-2017, tatu: Should only need to check ValueInstantiator for
                //    custom sub-classes, see [databind#1544]
                if (mapClass == EnumMap.class) {
                    inst = null;
                } else {
                    inst = findValueInstantiator(ctxt, beanDescRef);
                }
                if (!keyType.isEnumImplType()) {
                    throw new IllegalArgumentException("Cannot construct EnumMap; generic (key) type not available");
                }
                deser = new EnumMapDeserializer(type, inst, null,
                        contentDeser, contentTypeDeser, null);
            }

            // Otherwise, generic handler works ok.

            /* But there is one more twist: if we are being asked to instantiate
             * an interface or abstract Map, we need to either find something
             * that implements the thing, or give up.
             *
             * Note that we do NOT try to guess based on secondary interfaces
             * here; that would probably not work correctly since casts would
             * fail later on (as the primary type is not the interface we'd
             * be implementing)
             */
            if (deser == null) {
                if (type.isInterface() || type.isAbstract()) {

View on GitHub (pinned to a50c7d2a1d)

Solutions

  1. Declare the target with concrete generics: EnumMap<MyEnum, ValueType>.
  2. Use a TypeReference<EnumMap<MyEnum, ValueType>>(){} at read boundaries to preserve generic info.
  3. Avoid raw EnumMap; if unavoidable, deserialize into a concrete Map<MyEnum, ValueType> first, then copy into an EnumMap.
  4. Ensure the field/method signature carries the enum key type through the entire call chain.

Example fix

// before
Object result = mapper.readValue(json, EnumMap.class); // raw -> throws
// after
EnumMap<MyEnum, String> result = mapper.readValue(json,
        new TypeReference<EnumMap<MyEnum, String>>(){});
Defensive patterns

Strategy: validation

Validate before calling

JavaType t = mapper.getTypeFactory()
    .constructType(new TypeReference<EnumMap<MyEnum, X>>(){});
if (!t.getKeyType().isEnumType() || !t.getKeyType().isEnumImplType()) {
    throw new IllegalStateException("EnumMap key type is not a concrete enum: " + t.getKeyType());
}
mapper.readValue(json, t);

Prevention

When it happens

Trigger: Deserializing into a raw EnumMap (no type parameters), EnumMap<?, ?>, or a type where the key generic argument was erased or unavailable (raw field, Object-typed reference, or a TypeReference that doesn't carry the enum).

Common situations: Raw-typed fields/variables; reflective code that loses generics; JSON deserialized to Object then converted; interface return types that drop the enum parameter; legacy pre-generic APIs.

Related errors


AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06). Data as JSON: /api/errors/610f77d9f2b43c86. Report an issue: GitHub.