spring-cloud / spring-cloud/spring-cloud-gateway
PathRoutePredicateFactory: matchTrailingSlash has no effect since Spring Framework 7.0
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 4.9k
- Forks
- 3.5k
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 8
Description
Describe the bug
In Spring Cloud Gateway 5.0.x (built on Spring Framework 7.0 / Spring Boot 4), the matchTrailingSlash configuration on the Path route predicate no longer has any effect.
The root cause is that Spring Framework 7.0 removed PathPatternParser.setMatchOptionalTrailingSeparator() as part of spring-projects/spring-framework#34036. The Spring Cloud Gateway PathRoutePredicateFactory previously relied on this API to implement trailing slash tolerance.
In the current main branch of Spring Cloud Gateway, the call is commented out with a FIXME:
// FIXME: 5.0.0 setMatchOptionalTrailingSeparator missing
// pathPatternParser.setMatchOptionalTrailingSeparator(config.isMatchTrailingSlash());
This means the Config.matchTrailingSlash property still exists and is configurable, but silently does nothing — which is a breaking behavioral change for users relying on it.
Expected Behavior
When matchTrailingSlash is set to true (either globally or per-route), a path predicate like Path=/api/users/{segment} should match both:
/api/users/1/api/users/1/
This was the documented behavior prior to Spring Cloud Gateway 5.0.
Actual Behavior
The path predicate /api/users/{segment} only matches /api/users/1. A request to /api/users/1/ returns 404 regardless of the matchTrailingSlash setting.
Versions Affected
- Spring Cloud Gateway: 5.0.1
- Spring Framework: 7.0.7
- Spring Boot: 4.0.x
Spring's Original Behavior (pre-removal)
From the Spring Framework 6.2.x source (PathPatternParser Javadoc):
"If set to true a PathPattern without a trailing slash will also match request paths with a trailing slash."
The behavior was one-directional:
- Pattern
/api/usersmatches request/api/users/✓ - Pattern
/api/users/does NOT match request/api/users✗
The matching was handled internally by individual PathElement implementations during pattern traversal via MatchingContext.isMatchOptionalTrailingSeparator().
Sample
Since PathPatternParser no longer supports this natively, Spring Cloud Gateway should implement the trailing slash tolerance at the predicate level. A possible approach:
- When
matchTrailingSlashistrueand the initialPathPattern.matches(path)fails: - If the request path ends with
/, strip it and retry the match - Always restore the original path container in the exchange to avoid leaking state to downstream filters
This preserves the original one-directional semantics (patterns without trailing slash match requests with trailing slash) without depending on removed PathPatternParser internals.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at PathRoutePredicateFactory and its FIXME around the removed PathPatternParser trailing-separator API. Trace how the path is matched and how the exchange path is handled, then verify that matchTrailingSlash=true preserves the documented one-directional behavior for paths with and without a trailing slash, while the original path is restored afterward.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100