Backend Development 6 min read

Why Spring’s Functional Router Fails with /api Prefix and How to Fix It

This article explains a bug in Spring 6.1.11 where adding a servlet path prefix causes functional routing to throw an UnsupportedOperationException, demonstrates the issue with code and screenshots, and provides work‑arounds and the permanent fix introduced in Spring 6.1.12.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Why Spring’s Functional Router Fails with /api Prefix and How to Fix It

Environment : Spring 6.1.11 (used by SpringBoot 3.2.8).

Bug introduction : When using Spring Web MVC’s functional programming model (WebMvc.fn) – an alternative to the annotation‑based @RequestMapping – a specific nested route causes an exception.

1.1 Route interface definition

<code>@Bean
RouterFunction<ServerResponse> userRouter(UserHandler handler) {
    return route()
        .path("/routers/users", builder -> builder
            .GET("/{id}", accept(MediaType.TEXT_HTML), handler::findById))
        .build();
}</code>

1.2 Route handler

<code>@Component
public class UserHandler {
    public ServerResponse findById(ServerRequest request) {
        User user = new User(
            Long.valueOf(request.pathVariable("id")),
            request.param("name").orElse(null)
        );
        return ServerResponse.ok().body(user);
    }
}</code>

Testing the request works correctly (see screenshot).

1.3 Bug reproduction

Adding the following servlet path configuration introduces the error:

<code>spring:
  mvc:
    servlet:
      path: /api</code>

This configuration prefixes the DispatcherServlet path with /api . After the change, accessing /routers/users/* results in an error (see screenshots).

Explanation : The exception occurs only for nested routes; ordinary routes are unaffected.

2. Submitting an issue to Spring

The author reported the problem to the Spring team, who confirmed it and suggested a temporary workaround by setting the server context path:

<code>server:
  servlet:
    context-path: /api</code>

This workaround resolves the issue.

Permanent fix

The bug was fixed in Spring 6.1.12. Since SpringBoot 3.2.8 bundles Spring 6.1.11, you can either upgrade the Spring framework version in pom.xml :

<code>&lt;properties&gt;
  &lt;spring-framework.version&gt;6.1.12&lt;/spring-framework.version&gt;
&lt;/properties&gt;</code>

or avoid using nested functional routes.

Error cause

In Spring 6.1.11, ServletRequestPathUtils.modifyContextPath throws UnsupportedOperationException when handling nested routes:

<code>public abstract class ServletRequestPathUtils {
    private static final class ServletRequestPath implements RequestPath {
        // contextPath = /routers/users/6666 (no /api prefix yet)
        public RequestPath modifyContextPath(String contextPath) {
            // directly throws exception
            throw new UnsupportedOperationException();
        }
    }
}</code>

In Spring 6.1.12 the method was corrected to concatenate the configured servlet path prefix:

<code>private static final class ServletRequestPath implements RequestPath {
    public RequestPath modifyContextPath(String contextPath) {
        // Append /api to the current request path
        return new ServletRequestPath(this.pathElements.withContextPath(contextPath));
    }
}</code>

Thus, upgrading or avoiding nested functional routes resolves the problem.

JavaSpring BootBug Fixfunctional routingServlet PathWebMvc.fn
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.