Every Spring Boot 3.x branch left open-source support on 30 June 2026, and Spring Boot 4.0 follows in December 2026. The Java deadlines that get the headlines start in 2029, so for most Java teams the framework runs out of free security fixes years before the JDK does.
Spring Boot releases a new minor version about every six months and supports each one for free for about 13 months. A team that moves with that cycle does a small upgrade twice a year. A team that waits does a large one every few years, usually after a scanner or an auditor has found the gap.
Spring runs on a 13-month clock, Java on a much longer one
Oracle supports each Java LTS release with premier support for about five years and extended support for about three more. Spring Boot gives each minor branch about 13 months of open-source updates, then offers paid commercial support through Broadcom's Tanzu Spring for a further period (Dan Vega, "Spring Boot End of Life", July 2026). Spring Boot 4.1 was released on 10 June 2026 (spring.io).
| Spring Boot branch | Released | Open-source support ends | Commercial support ends |
|---|---|---|---|
| 2.7 | May 2022 | June 2023 | June 2029 |
| 3.5 (and every 3.x) | May 2025 | 30 June 2026 | June 2032 |
| 4.0 | November 2025 | December 2026 | December 2027 |
| 4.1 | June 2026 | July 2027 | July 2028 |
Spring Framework follows the same pattern underneath: 6.2, the version under Boot 3.5, left open-source support with it, and 7.0 is the line that receives free fixes now. The Java dates for 8, 11, 17, 21 and 25, and what Oracle's October 2026 licence change means for JDK 21, are in our Java support calendar.
Out of open-source support means the fix exists, but not for your branch
When a branch leaves open-source support, the Spring team keeps fixing it, but the fixed builds go to the commercial repository instead of Maven Central. The Spring Framework 6.2.19 release on 8 June 2026 fixed 19 CVEs, and the announcement called it "most probably the last OSS release of the 6.2.x generation" (spring.io).
The first advisories after the cut-off show what this means. CVE-2026-47884, published on 20 August 2026, describes how XsltView in a Spring MVC application can allow server-side request forgery and remote code execution when a catch-all mapping renders a view without an explicit name. It affects Spring Framework 6.2.0 to 6.2.19. The open-source fix is 7.0.9; the fix for the 6.2 line, 6.2.20, is available to enterprise customers only (spring.io advisory). Spring rates it medium and the conditions are narrow. For a team on 3.x, later advisories will follow the same pattern: a fix exists, in a version that is not on Maven Central.
The volume of advisories is also rising. HeroDevs counted 67 Spring CVEs published in June 2026, 27 of them rated high, against 17 in the whole of 2025 (HeroDevs). HeroDevs sells extended support for end-of-life Spring versions, so read its framing with that in mind; the monthly totals can be checked against the spring.io advisory list. Steve Poole adds a quieter problem: once a line is out of support, advisories stop evaluating whether it is affected, so a dependency scanner can report an old branch as clean when nobody has checked it (Foojay, April 2026).
For a team on 3.x, the vulnerability count in the scanner will only go up from here, and part of the real count may not show at all. Our vulnerability remediation work starts with exactly this gap: which advisories apply to the versions you run, and which of them the scanner cannot see.
Paying for support to 2032 against upgrading: the break-even
Commercial support is a real option, and for some systems it is the right one. Neither Tanzu Spring nor HeroDevs publishes prices; both quote per customer. The comparison therefore has to be made with your own quote, against your own upgrade estimate.
The table gives the upgrade side, from our own work. These are planning ranges, not a benchmark: the actual effort depends on test coverage and on how many third-party libraries have a release for the new version.
| Codebase | 3.5 to 4.x | 2.7 to 3.5, then 4.x | Either route at an illustrative EUR 800 per engineer-day |
|---|---|---|---|
| Single service, one team | 3 to 10 engineer-days | 10 to 25 engineer-days | EUR 2,400 to 20,000 |
| Mid-size application, several integrations | 10 to 30 engineer-days | 25 to 60 engineer-days | EUR 8,000 to 48,000 |
| Large monolith, many integrations and custom starters | 30 to 80 engineer-days | 60 to 150 engineer-days | EUR 24,000 to 120,000 |
Support is paid every year and does not remove the upgrade; it moves it. Commercial support for 4.0 ends in December 2027, and for 4.1 in July 2028, so a team that buys support for the 4.x line is still upgrading within about two years. The one long window is 3.5, with commercial support to June 2032, which makes paying a reasonable choice for a system that is due to be retired or replaced before then. For a system that will still be changing in 2030, the upgrade costs the same or more later, and the support fee is paid on top.
3.5 to 4.x is smaller than 2.7 to 3.0 was, and the work is in the dependencies
The move from 2.7 to 3.0 was hard because it changed the ground under every application: Java 17 as the minimum, and the rename of every javax package to jakarta. Spring Boot 4 keeps Java 17 as its baseline and has no namespace change. Most of the work is in the libraries it brings along: Spring Framework 7, Spring Security 7, Hibernate 7.2, Jackson 3, Tomcat 11 and Jetty 12.1 (Spring Boot 4.0 release notes).
| Change | What breaks | How you find it |
|---|---|---|
| Jackson 3 packages | The group ID moves from com.fasterxml.jackson to tools.jackson; @JsonComponent becomes @JacksonComponent; Jackson2ObjectMapperBuilderCustomizer becomes JsonMapperBuilderCustomizer | Compile errors; OpenRewrite recipes cover most of it |
| Jackson 3 defaults | Dates are written as ISO-8601 strings instead of numeric timestamps, properties are sorted alphabetically, and unknown properties no longer fail deserialization | Nothing fails to compile. Only tests that compare JSON output, or your API consumers, will notice |
| Modular starters | Auto-configuration is split into focused modules, so technologies such as Flyway and Liquibase need their own starter | A database migration that silently stops running at startup; spring-boot-starter-classic works as a temporary bridge |
| Test support | @MockBean and @SpyBean are removed in favour of @MockitoBean and @MockitoSpyBean; @SpringBootTest no longer provides MockMvc or TestRestTemplate by itself | Compile errors and failing tests; add @AutoConfigureMockMvc or @AutoConfigureTestRestTemplate |
| Removals | Undertow is gone because it does not support Servlet 6.1, and every API deprecated in 3.x is removed | Build errors; fixing deprecation warnings on 3.5 first removes most of them |
| Renamed properties | Some configuration keys moved, for example MongoDB settings split between spring.mongodb and spring.data.mongodb | The spring-boot-properties-migrator dependency reports them at startup |
| Null-safety annotations | JSpecify annotations across Spring can fail builds that use Kotlin or a null checker | Compile errors, usually a quick fix per call site |
The Jackson defaults are the row we would test first. An upgrade that compiles, passes its unit tests and then changes the date format in a public API breaks its clients, and the first report comes from outside the team. A handful of contract tests that pin the JSON of the main endpoints, written on 3.5 before the upgrade, turns that into a failing build. Setting spring.jackson.use-jackson2-defaults to true brings the Jackson 2 behaviour back, which is a reasonable first step if the API cannot change yet (Spring Boot 4.0 migration guide).
Spring Boot 4 also brings features worth having
An upgrade that brings only security fixes is hard to schedule against feature work. Spring Boot 4 adds enough to make the case on its own terms (4.0 release notes, 4.1 announcement):
- HTTP service clients. A plain Java interface with annotations becomes a client for an external API, with the implementation generated by Spring. Hand-written
RestTemplatewrappers for each API are no longer needed. - API versioning. Spring MVC and WebFlux get auto-configured versioning through
spring.mvc.apiversion.*properties, in place of the custom header or path conventions most teams built themselves. - OpenTelemetry. A new
spring-boot-starter-opentelemetryexports metrics and traces over OTLP with little configuration. - Smaller, focused modules. The same split that causes the starter work in the table above means an application loads only the auto-configuration it uses.
- In 4.1: Spring gRPC support, and SSRF protection for HTTP clients through an address filter.
Still on 2.7? Two deployable steps, one plan
The Spring Boot 4.0 migration guide starts with one instruction: upgrade to the latest 3.5.x first. For a 2.7 application, that makes the route two steps. The first, 2.7 to 3.5, carries the expensive changes: Java 17, the jakarta namespace, Hibernate 6 and Spring Security 6. The second, 3.5 to 4.x, carries the dependency work in the table above. Each step goes to production on its own, so a regression points to one set of changes.
Planning both steps together still pays, because the same inventory serves both: which libraries have no release for Jakarta or for Jackson 3, which custom starters need rewriting, and which flows have no tests. Moderne published the numbers from its own move from Spring Boot 2 to 3.2, which included Java 8 to 17 and JUnit 4 to 5: 37 repositories and 2,700 files, with OpenRewrite recipes automating 80 to 90% of the work and the whole run taking under a day from recipe to merged pull requests (Moderne). The work the recipes did not cover: JAXB dependencies across dozens of repositories, three major versions of the DGS GraphQL framework, the HttpStatus and HttpMethod changes in Spring Framework 6, and transitive dependencies that disappeared. Moderne also deployed its most-changed services first, so the teams doing feature work moved onto the new version early, and kept its services backward compatible while old and new versions ran side by side.
For systems where the upgrade exposes a design problem, not only old versions, the strangler fig pattern lets you move one slice at a time, and our guide to application modernization covers how to decide which system goes first.
Two weeks of preparation on 3.5 make the 4.0 move predictable
Most of the risk in a Spring Boot 4 upgrade can be found before the version number changes. On a mid-size application, the steps below take one engineer about two weeks, and they leave a list of known work in place of an open-ended estimate.
- Find out what each repository runs. For Maven,
mvn dependency:tree -Dincludes=org.springframework.boot:spring-bootprints the Boot version in use; do the same for Spring Framework, Jackson and Hibernate, because a managed version can be overridden in the build. - Move to the latest 3.5.x. The 4.0 migration guide asks for it, and it brings the last deprecation warnings before the removals.
- Make deprecation warnings visible and fix them. Add
-Xlint:deprecationto the compiler arguments. Every warning left on 3.5 becomes a compile error on 4.0. - Pin the JSON. Write contract tests for the main endpoints and messages, so the Jackson 3 defaults show up as test failures.
- Check third-party libraries.
mvn versions:display-dependency-updateslists what has newer releases; the question for each library is whether a version supports Jakarta EE 11 and Jackson 3. A library with no such release is the item most likely to stretch the schedule, so it goes to the top of the list. - Run the upgrade recipe as a dry run. OpenRewrite's dry run writes a patch without changing the code, which shows the size of the mechanical change before anyone commits to a date:
mvn -U org.openrewrite.maven:rewrite-maven-plugin:dryRun \
-Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-spring:RELEASE \
-Drewrite.activeRecipes=org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0
The recipe also applies the Spring Framework 7 and Spring Security 7 migrations (OpenRewrite docs). What it leaves behind, together with the libraries from step 5, is the estimate to plan with. On the first start on 4.0, add spring-boot-properties-migrator to catch renamed configuration keys, and remove it once the logs are clean.
How a small team runs an upgrade train
Netflix started moving its Java services to Spring Boot 3 and Java 17 in June 2022. At SpringOne in 2023, Asi Bross described the scope as 3,000 applications and 1,500 libraries, run by a platform team of five engineers who automated as much of each upgrade as they could (Tanzu). By JavaOne 2026 Netflix was fully on Spring Boot 3 and had started on Spring Boot 4 with AI-assisted tooling; notes from Paul Bakker's talk record the rule behind it as upgrading sooner, and therefore more often (talk notes, March 2026).
A team of five to ten engineers does not have a platform team, but the same rule works at that size with a few habits:
- Move to each new Spring Boot minor within about three months of its release. With a release every six months and 13 months of free support, that keeps every application on a supported branch with room to spare.
- Let Dependabot or Renovate open patch updates automatically, and merge them when the build passes. Patch releases are where the security fixes arrive.
- Fix deprecation warnings on the current version, every minor. Spring removes deprecated APIs in the next major, so a clean build on 3.5 is most of the move to 4.0.
- Keep contract tests on the JSON of the main endpoints, so library upgrades that change serialization fail in the build.
- Take one version step per deployment: the JDK, or Spring Boot, or the build tool, not all three at once.
Earlier this year we moved a fifteen-year-old online store and back-office system for a wine merchant from Java 17 and Spring 5.3 to Java 25 and Spring 6.2, and cut its critical and high-severity advisories from 47 to none (case study). Spring 6.2 has since left open-source support. That upgrade was the right step from where the system started, and today we would take it on to Spring Framework 7 and, for Boot applications, to Spring Boot 4.1. A modernization that ends on a version with a year of support left needs an upgrade train after it.
If you are not sure which branch each of your applications runs, or in which order to move them, that is what the first step of our Application Modernization Sprint produces: an inventory of versions and support dates, the order to move, and a ballpark estimate, within a week of a thirty-minute call.