🚨 Spring Boot 3.x 4.0 Migration: What Actually Broke (and How We Fixed It)

Published: (January 30, 2026 at 05:48 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

Spring Boot 4.0 migration looks straightforward on paper: update dependencies.
In reality, things break—quietly, repeatedly, and sometimes in places you don’t expect.
We recently migrated a production application from Spring Boot 3.x to 4.0 and want to share what actually broke, why it broke, and how we fixed it, so you don’t lose days chasing cryptic errors.

Jakarta Namespace Issues

Symptom

Even if you migrated to Jakarta in Spring Boot 3.x, some transitive dependencies still pull javax.* classes. Common offenders include:

  • old validation libraries
  • SOAP / JAXB tooling
  • legacy servlet filters

Fix

mvn dependency:tree | grep javax

Then:

  • Force Jakarta‑compatible versions.
  • Exclude old transitive dependencies explicitly.

Lesson: “It worked in 3.x” doesn’t mean it’s safe in 4.0.

Spring Security Configuration Changes

Symptom

Spring Security in the Spring Boot 4 era expects fully explicit configuration. What broke:

  • Deprecated DSLs removed.
  • Defaults changed (especially CSRF & session handling).
  • Custom filters no longer auto‑registered.

Fix

Move to explicit SecurityFilterChain beans and stop relying on defaults.

@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf(csrf -> csrf.disable())
        .authorizeHttpRequests(auth -> auth.anyRequest().authenticated());
    return http.build();
}

Lesson: Implicit security configs are gone; be explicit or be surprised.

Starter Renames, Splits, and Removals

Symptom

Several Spring Boot starters were renamed, split, or removed entirely, especially around:

  • Observability
  • Actuator extensions
  • Legacy integrations

Fix

Audit your starters manually; don’t trust the old list.

mvn dependency:tree | grep spring-boot-starter

Replace removed starters with:

  • Explicit libraries, or
  • New modular alternatives.

Java Baseline Mismatch (Java 21+)

Symptom

Spring Boot 4.0 pushes modern Java harder (Java 21+). What broke:

  • Testcontainers images
  • ByteBuddy / Mockito compatibility
  • JVM flags removed or ignored

Fix

  • Align local Java version, CI Java version, and Maven toolchains.
  • Upgrade testing libraries aggressively.

Lesson: Don’t debug Spring errors when it’s really a JVM mismatch.

Observability Defaults Refactor

Symptom

Spring Boot 4 refactors observability defaults:

  • Endpoints disabled by default
  • Renamed metrics
  • Different exposure rules

Fix

Re‑declare actuator exposure explicitly:

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics

Lesson: “No error” ≠ “working”.


Migration Checklist & Further Reading

We documented every breaking change, fix, and gotcha into a structured migration checklist.

Full Spring Boot 3.x → 4.0 migration guide
🔗

It includes:

  • Dependency audit steps
  • Security migration patterns
  • Test & CI fixes
  • Actuator & observability changes

We’re building a small directory of real‑world migration guides (not marketing docs):
🔗

If you’re dealing with Spring Boot upgrades, Java version jumps, or framework migrations, you’ll probably find something useful there.

What was the weirdest thing that broke during your Spring Boot upgrade?
Silent behavior change?
Let’s compare notes 👇

Back to Blog

Related posts

Read more »

Day-4 Data Types

Data types Data types are the kinds of information stored in a variable e.g., numbers, characters, true/false, etc.. There are two categories of data types: -...

Day-3 details of Class and Object

Class - Class is a Java keyword - Class is a template - Class is a logical entity - First letter of the class name should be capital CamelCase, e.g., SalaryAcc...

Instance(Object) Variable

What is an Instance Variable in Java? - An instance variable is a variable that belongs to an object instance of a class. - Every object gets its own copy of t...