Description
When spring.jackson.use-jackson2-defaults=true is set in Spring Boot 4.0.4 (also verified in 4.0.5), DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES is enabled (true). In Spring Boot 3, Jackson2ObjectMapperBuilder.customizeDefaultFeatures() explicitly disabled this feature (false).
The Configuration Changelog describes this property as: "Whether to configure Jackson 3 with the same defaults as Spring Boot previously used for Jackson 2."
We wanted to check whether this is expected behavior or an oversight.
Spring Boot 3 Behavior (reference)
Jackson2ObjectMapperBuilder.customizeDefaultFeatures() disables FAIL_ON_UNKNOWN_PROPERTIES by default:
private void customizeDefaultFeatures(ObjectMapper objectMapper) {
if (!this.features.containsKey(MapperFeature.DEFAULT_VIEW_INCLUSION)) {
configureFeature(objectMapper, MapperFeature.DEFAULT_VIEW_INCLUSION, false);
}
if (!this.features.containsKey(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
configureFeature(objectMapper, DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
}
Note: This class still exists in Spring Framework 7 (spring-web-7.0.6.jar) and still disables FAIL_ON_UNKNOWN_PROPERTIES, but it only applies to the Jackson 2 path.
Observed Behavior in Spring Boot 4
Decompiled from spring-boot-jackson-4.0.4.jar, JacksonAutoConfiguration$AbstractMapperBuilderCustomizer:
// Calls configureForJackson2() which ENABLES FAIL_ON_UNKNOWN_PROPERTIES (raw Jackson 2 library default)
11: invokevirtual #23 // MapperBuilder.configureForJackson2()
// Then disables WRITE_DATES_AS_TIMESTAMPS and WRITE_DURATIONS_AS_TIMESTAMPS (restoring SB3 behavior for dates)
20: getstatic #31 // DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS
26: getstatic #37 // DateTimeFeature.WRITE_DURATIONS_AS_TIMESTAMPS
30: invokevirtual #40 // MapperBuilder.disable()
// No further override of FAIL_ON_UNKNOWN_PROPERTIES
Jackson 3's MapperBuilder.configureForJackson2() (decompiled from jackson-databind-3.1.0.jar):
// Enables FAIL_ON_UNKNOWN_PROPERTIES = true (raw Jackson 2 library default)
85: getstatic #460 // DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
89: invokevirtual #463 // MapperBuilder.enable()
Spring Boot 4 calls configureForJackson2() then overrides dates/durations, but does not re-disable FAIL_ON_UNKNOWN_PROPERTIES to match SB3's Jackson2ObjectMapperBuilder behavior.
Additional Checks
- Searched all classes in
spring-boot-jackson-4.0.4.jar and spring-boot-jackson-4.0.5.jar — no reference to FAIL_ON_UNKNOWN_PROPERTIES
- Searched all other
spring-boot-*-4.0.4.jar modules — no reference
- Jackson 3's own default for
FAIL_ON_UNKNOWN_PROPERTIES is false (verified via bytecode)
DEFAULT_VIEW_INCLUSION is NOT affected — Jackson 3 already defaults to false and configureForJackson2() does not set it
Impact
With use-jackson2-defaults=true, deserializing JSON with unknown fields throws UnrecognizedPropertyException. For example, Spring's Page response contains pageable, sort, first, last, empty, numberOfElements fields that a simplified DTO may not include. This worked in Spring Boot 3 and works without use-jackson2-defaults.
Reproduction
spring:
jackson:
use-jackson2-defaults: true
@SpringBootTest
class Jackson2DefaultsTest {
@Autowired
private JsonMapper jsonMapper;
@Test
void failOnUnknownPropertiesShouldBeFalse() {
// Fails — returns true instead of false
assertThat(jsonMapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)).isFalse();
}
}
Workaround
spring:
jackson:
use-jackson2-defaults: true
deserialization:
fail-on-unknown-properties: false
Environment
- Spring Boot 4.0.4 and 4.0.5
- Jackson 3.1.0
- Java 25 (Corretto)
Related
Description
When
spring.jackson.use-jackson2-defaults=trueis set in Spring Boot 4.0.4 (also verified in 4.0.5),DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIESis enabled (true). In Spring Boot 3,Jackson2ObjectMapperBuilder.customizeDefaultFeatures()explicitly disabled this feature (false).The Configuration Changelog describes this property as: "Whether to configure Jackson 3 with the same defaults as Spring Boot previously used for Jackson 2."
We wanted to check whether this is expected behavior or an oversight.
Spring Boot 3 Behavior (reference)
Jackson2ObjectMapperBuilder.customizeDefaultFeatures()disablesFAIL_ON_UNKNOWN_PROPERTIESby default:Note: This class still exists in Spring Framework 7 (
spring-web-7.0.6.jar) and still disablesFAIL_ON_UNKNOWN_PROPERTIES, but it only applies to the Jackson 2 path.Observed Behavior in Spring Boot 4
Decompiled from
spring-boot-jackson-4.0.4.jar,JacksonAutoConfiguration$AbstractMapperBuilderCustomizer:Jackson 3's
MapperBuilder.configureForJackson2()(decompiled fromjackson-databind-3.1.0.jar):Spring Boot 4 calls
configureForJackson2()then overrides dates/durations, but does not re-disableFAIL_ON_UNKNOWN_PROPERTIESto match SB3'sJackson2ObjectMapperBuilderbehavior.Additional Checks
spring-boot-jackson-4.0.4.jarandspring-boot-jackson-4.0.5.jar— no reference toFAIL_ON_UNKNOWN_PROPERTIESspring-boot-*-4.0.4.jarmodules — no referenceFAIL_ON_UNKNOWN_PROPERTIESisfalse(verified via bytecode)DEFAULT_VIEW_INCLUSIONis NOT affected — Jackson 3 already defaults tofalseandconfigureForJackson2()does not set itImpact
With
use-jackson2-defaults=true, deserializing JSON with unknown fields throwsUnrecognizedPropertyException. For example, Spring'sPageresponse containspageable,sort,first,last,empty,numberOfElementsfields that a simplified DTO may not include. This worked in Spring Boot 3 and works withoutuse-jackson2-defaults.Reproduction
Workaround
Environment
Related
use-jackson2-defaults