spring-projects/spring-security · error · IllegalArgumentException

Spring Security and Spring MVC must use the same path…

Error message

Spring Security and Spring MVC must use the same path pattern parser. To have Spring Security use Spring MVC's [{mvcParser}] simply publish this bean [{thisBean}] using its default constructor

What it means

PathPatternRequestMatcherBuilderFactoryBean aligns Spring Security's request-matching with Spring MVC's PathPatternParser. If the effective parser (custom injected parser or default) differs from the one Spring MVC uses in the context, getObject() throws IllegalArgumentException because security and MVC would interpret URL paths differently.

Solutions

  1. Publish PathPatternRequestMatcher.Builder using its default constructor so it adopts Spring MVC's parser
  2. Change the custom parser so it equals the MVC parser instance/config
  3. If MVC's parser must differ, adjust MVC pathmatch configuration so both sides match

Example fix

// before
@Bean
PathPatternRequestMatcher.Builder securityMatcherBuilder() {
  return new PathPatternRequestMatcher.Builder(PathPatternParser.defaultInstance);
}

// after
@Bean
PathPatternRequestMatcher.Builder securityMatcherBuilder() {
  return new PathPatternRequestMatcher.Builder(); // uses Spring MVC's parser
}
Defensive patterns

Strategy: validation

Validate before calling

PathPatternParser mvc = context.getBean("webMvcPathPatternParser", PathPatternParser.class);
PathPatternParser securityParser = /* parser you configured */;
if (!mvc.equals(securityParser)) {
  throw new IllegalStateException("Security and MVC path parsers differ; use the default constructor");
}

Prevention

When it happens

Trigger: Publishing PathPatternRequestMatcher.Builder with a non-default constructor/parser (e.g. withPathPatternParser() with a different parser instance) while a Spring MVC PathPatternParser bean exists and they are not equal.

Common situations: Customizing the parser via a custom bean definition after upgrading to Spring Security 7; mixing AntPathMatcher-based settings with MVC's pathpattern matching; bootstrapping the builder with a constructor argument in a MVC app.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/5331a6eb5f2a0b69. Report an issue: GitHub.

Appendix: source

Thrown at config/src/main/java/org/springframework/security/config/web/PathPatternRequestMatcherBuilderFactoryBean.java:89

	 * Please call the default constructor instead.
	 * @param parser the {@link PathPatternParser} to use
	 */
	public PathPatternRequestMatcherBuilderFactoryBean(PathPatternParser parser) {
		this.parser = parser;
	}

	@Override
	public PathPatternRequestMatcher.Builder getObject() throws Exception {
		if (!this.context.containsBean(MVC_PATTERN_PARSER_BEAN_NAME)) {
			PathPatternParser parser = (this.parser != null) ? this.parser : PathPatternParser.defaultInstance;
			return withPathPatternParser(parser);
		}
		PathPatternParser mvc = this.context.getBean(MVC_PATTERN_PARSER_BEAN_NAME, PathPatternParser.class);
		PathPatternParser parser = (this.parser != null) ? this.parser : mvc;
		if (mvc.equals(parser)) {
			return withPathPatternParser(parser);
		}
		throw new IllegalArgumentException("Spring Security and Spring MVC must use the same path pattern parser. "
				+ "To have Spring Security use Spring MVC's [" + describe(mvc, MVC_PATTERN_PARSER_BEAN_NAME)
				+ "] simply publish this bean [" + describe(this, this.beanName) + "] using its default constructor");
	}

	private PathPatternRequestMatcher.Builder withPathPatternParser(PathPatternParser parser) {
		if (this.basePath == null) {
			return PathPatternRequestMatcher.withPathPatternParser(parser);
		}
		else {
			return PathPatternRequestMatcher.withPathPatternParser(parser).basePath(this.basePath);
		}
	}

	@Override
	public Class<?> getObjectType() {
		return PathPatternRequestMatcher.Builder.class;
	}

View on GitHub (pinned to 96852e8860)