{"record":{"id":"69a081b17d10de67","repo":"FasterXML/jackson-databind","slug":"deserializationproblemhandler-handlenullforprimit","errorCode":null,"errorMessage":"`DeserializationProblemHandler.handleNullForPrimitives()` for type %s returned value of type %s","messagePattern":"`DeserializationProblemHandler\\.handleNullForPrimitives\\(\\)` for type (.+?) returned value of type (.+?)","errorType":"exception","errorClass":"InvalidFormatException","httpStatus":null,"severity":"error","filePath":"src/main/java/tools/jackson/databind/DeserializationContext.java","lineNumber":1575,"sourceCode":"     */\n    public Object handleNullForPrimitives(Class<?> targetClass,\n            JsonParser p, ValueDeserializer<?> deser,\n            String msgTemplate, Object... msgArgs)\n        throws JacksonException\n    {\n        // but if not handled, just throw exception\n        LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();\n        String msg = _format(msgTemplate, msgArgs);\n        while (h != null) {\n            // Can bail out if it's handled\n            Object instance = h.value().handleNullForPrimitives(this, targetClass, p, deser, msg);\n            if (instance != DeserializationProblemHandler.NOT_HANDLED) {\n                // Sanity check for broken handlers, otherwise nasty to debug:\n                if (_isCompatible(targetClass, instance)) {\n                    return instance;\n                }\n                // In case our problem handler providing incompatible value,\n                throw new InvalidFormatException(_parser,\n                        \"`DeserializationProblemHandler.handleNullForPrimitives()` for type %s returned value of type %s\".formatted(\n                                ClassUtil.nameOf(targetClass), ClassUtil.getClassDescription(instance)),\n                    instance, targetClass\n                        );\n            }\n            h = h.next();\n        }\n        return reportInputMismatch(deser, msg);\n    }\n    /**\n     * Method that deserializers should call if they fail to instantiate value\n     * due to lack of viable instantiator (usually creator, that is, constructor\n     * or static factory method). Method should be called at point where value\n     * has not been decoded, so that handler has a chance to handle decoding\n     * using alternate mechanism, and handle underlying content (possibly by\n     * just skipping it) to keep input state valid\n     *\n     * @param instClass Type that was to be instantiated","sourceCodeStart":1557,"sourceCodeEnd":1593,"githubUrl":"https://github.com/FasterXML/jackson-databind/blob/a50c7d2a1d57234ac4adf70dbd88ac90db6436e4/src/main/java/tools/jackson/databind/DeserializationContext.java#L1557-L1593","documentation":"When a JSON null is encountered for a primitive Java field and a DeserializationProblemHandler is registered, Jackson gives the handler a chance to substitute a default value via handleNullForPrimitives(). If the handler returns an object whose type is not compatible (assignable) to the target primitive wrapper type, Jackson throws InvalidFormatException rather than silently mis-boxing the value. This is a sanity guard against buggy/problematic handlers that would otherwise produce ClassCastException downstream.","triggerScenarios":"A registered DeserializationProblemHandler.handleNullForPrimitives() returns, e.g., a String for an int field, a Long for a boolean, or null for a primitive that the handler claimed to handle; returning a boxed type that doesn't match (e.g. Double for a float field is fine, but Integer for a double is not, depending on widening rules).","commonSituations":"Writing a 'null to default' handler that returns a single sentinel object for all primitives; a handler returning a value computed from the wrong field/type after refactoring; 2.x handlers ported to 3.x where the primitive type passed in changed signature; handler returns 0 for int but is also invoked for boolean and returns the same 0 (boxing to Integer, incompatible with boolean).","solutions":["In your handleNullForPrimitives(), branch on targetClass and return the correct boxed primitive type (Integer for int.class/Integer.class, Boolean for boolean, Double for double, etc.).","Use the targetClass argument passed to the handler to produce a compatible value, and return DeserializationProblemHandler.NOT_HANDLED for types you don't specifically handle.","Add a unit test that exercises the handler for every primitive type it might be called for.","If you want a global default, prefer @JsonSetter(nulls=AS_DEFAULT) or DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_DEFAULT etc. rather than a broad handler."],"exampleFix":"// before\n@Override\npublic Object handleNullForPrimitives(DeserializationContext ctxt, Class<?> primitiveType,\n        JsonParser p, ValueDeserializer<?> deser, String failureMsg) {\n    return 0; // wrong for boolean/double!\n}\n// after\n@Override\npublic Object handleNullForPrimitives(DeserializationContext ctxt, Class<?> primitiveType,\n        JsonParser p, ValueDeserializer<?> deser, String failureMsg) {\n    if (primitiveType == int.class || primitiveType == Integer.class) return Integer.valueOf(0);\n    if (primitiveType == boolean.class || primitiveType == Boolean.class) return Boolean.FALSE;\n    return NOT_HANDLED;\n}","handlingStrategy":"validation","validationCode":"// Validate a handler's return type matches the primitive target before relying on it\nstatic Object checkedNullDefault(Class<?> prim, Object v) {\n    if (v == DeserializationProblemHandler.NOT_HANDLED) return v;\n    if (v == null || !box(prim).isInstance(v)) {\n        throw new IllegalStateException(\"handler returned incompatible \" + v);\n    }\n    return v;\n}\nstatic Class<?> box(Class<?> p) {\n    return java.lang.invoke.MethodHandles.reflectLookup(p); // pseudo; use a primitive-box map\n}","typeGuard":"boolean compatibleWithPrimitive(Class<?> prim, Object v) {\n    // crude check using a primitive->wrapper map\n    return v != null && _isCompatible(prim, v);\n}","tryCatchPattern":"try {\n    return mapper.readValue(json, Bean.class);\n} catch (InvalidFormatException e) {\n    if (e.getMessage().contains(\"handleNullForPrimitives\")) {\n        // fix handler, do not blanket-ignore\n    }\n    throw e;\n}","preventionTips":["Branch on the target primitive class in your handler and return the matching wrapper.","Return NOT_HANDLED for any primitive type your handler does not explicitly cover.","Unit-test the handler against every primitive/wrapper type it might be invoked for.","Prefer field-level @JsonSetter(nulls=AS_DEFAULT) or @JsonInclude defaults over a broad handler."],"tags":["deserialization","null-handling","problem-handler","primitive"],"analyzedSha":"a50c7d2a1d57234ac4adf70dbd88ac90db6436e4","analyzedAt":"2026-08-06T20:31:51.404Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}