No More Pattern Data Allowed After *{...} or ** Pattern Element - A Journey Through Resolving the Issue


As a developer, you occasionally run into errors that seem straightforward but, after diving deeper, turn into challenging puzzles. I recently faced one such issue when working with Spring Boot and Spring Security. The error message was frustratingly simple yet complex:

Error Message: No more pattern data allowed after `{*...}` or `**` pattern element.

I knew it had to do with how patterns in path matching were handled, but I wasn’t exactly sure why it was failing. After multiple trial and error sessions and digging into resources online, I finally managed to crack the issue. 

Here’s how I solved it—and hopefully, this guide can save you some trouble if you run into the same problem.

Understanding the Cause of the Error

The error popped up while I was upgrading from an older Spring Boot version to a newer one. The problem originates from a change in Spring Security 6's path matching rules, where *{...} and ** are treated more strictly. 

In earlier versions, these patterns allowed more flexibility, but now, they’ve become restrictive in an attempt to make path matching more precise.

With *{...}, Spring expects a well-defined structure, meaning that if a wildcard is used incorrectly or additional data is provided after it, Spring won’t know how to interpret it. 

The same applies to the double ** wildcard, which is now restricted in how it can be used in path patterns.

Finding Solutions

After combing through forums, documentation, and other resources, here’s what I found about solving this error effectively.

Solution 1: Adjust Path Patterns to Match New Spring Standards

If you’re using patterns with both * and **, it’s essential to follow Spring’s updated path structure. Here’s an example of a problematic path pattern I initially had:

// Old pattern that threw an error
"/api/**/users/*/details"

This pattern was problematic because it combined ** with a more specific path section after it, which is now restricted.

Updated Code:

// Revised pattern for compatibility with Spring Security 6
"/api/{path}/users/{userId}/details"

In this approach, I replaced ** and * with explicit placeholders, making it more in line with Spring’s stricter matching rules.

Solution 2: Using Ant Path Patterns in a More Limited Scope

Spring Security’s antMatchers() method, which previously accepted flexible wildcards, now demands more strict adherence. If you need to use **, keep it to the end of your pattern and avoid additional characters. Here’s an example:

// Working example with `**` at the end only
"/api/**"

This pattern is allowed because it has a clear start and finish with ** at the endpoint. Using ** in between segments will likely cause errors.

Solution 3: Explicitly Configure Path Matching in WebSecurityConfigurerAdapter

Another solution that worked for me involved tweaking the security configuration to handle custom path matching more effectively. Here’s what I did:

  1. Created a custom PathMatcher.
  2. Overrode the default settings in WebSecurityConfigurerAdapter.

Code Example:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/api/**").permitAll()
            .anyRequest().authenticated();
    }
}

By specifying my paths directly in antMatchers, I avoided issues that arose from ambiguous patterns.

Solution 4: Fall Back to Java Configuration Instead of Annotations

In some cases, using @RequestMapping annotations with complex patterns led to unexpected behavior. Moving the configuration to Java code with WebSecurityConfigurerAdapter and HttpSecurity sometimes provided greater control.

For example, this setup caused errors when used with @RequestMapping:

@GetMapping("/api/**/users/{id}")
public ResponseEntity getUser(@PathVariable String id) {
    // code
}

Switching this to the WebSecurity configuration fixed the error:

.antMatchers("/api/**/users/*").permitAll()

Solution 5: Reconsider PathPatternParser for Path Matching

Spring 5 introduced PathPatternParser as an alternative to AntPathMatcher. If you’re encountering frequent path errors, try enabling PathPatternParser in your configuration. It provides more predictable matching behavior.

Code Example:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setPatternParser(new PathPatternParser());
    }
}

With PathPatternParser, you’ll get more reliable path handling, especially in complex applications.