Skip to content

With spring.jackson.use-jackson2-defaults set to true, FAIL_ON_UNKNOWN_PROPERTIES is enabled #49951

@jackkang-jaris

Description

@jackkang-jaris

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

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions