spring-projects/spring-security · error · BeanDefinitionStoreException

You cannot use bearer-token-ref and…

Error message

You cannot use bearer-token-ref and authentication-converter-ref in the same oauth2-resource-server element

What it means

The <oauth2-resource-server> XML element supports configuring bearer token resolution either via bearer-token-ref or converting the request via authentication-converter-ref — but not both simultaneously. parse() (OAuth2ResourceServerBeanDefinitionParser.java:133) throws BeanDefinitionStoreException when both attributes are present, because combining them would create ambiguous authentication handling.

Solutions

  1. Remove bearer-token-ref and keep only authentication-converter-ref.
  2. Alternatively remove authentication-converter-ref and keep only bearer-token-ref.
  3. If both behaviors are needed, implement a custom authentication converter that internally uses the desired BearerTokenResolver.

Example fix

// before
<oauth2-resource-server bearer-token-ref="myResolver" authentication-converter-ref="myConverter"/>
// after
<oauth2-resource-server authentication-converter-ref="myConverter"/>
Defensive patterns

Strategy: validation

Validate before calling

Element el = /* oauth2-resource-server element */;
if (el.hasAttribute("bearer-token-ref") && el.hasAttribute("authentication-converter-ref")) {
  throw new IllegalArgumentException("bearer-token-ref and authentication-converter-ref are mutually exclusive");
}

Try / catch

try { new OAuth2ResourceServerBeanDefinitionParser().parse(el, pc); } catch (BeanDefinitionStoreException e) { if (e.getMessage().contains("bearer-token-ref")) { log.error("Remove one of bearer-token-ref / authentication-converter-ref", e); } throw e; }

Prevention

When it happens

Trigger: Defining <oauth2-resource-server bearer-token-ref="..." authentication-converter-ref="..."/> in the XML namespace; both getBearerTokenResolver and getAuthenticationConverter return non-null from the same element.

Common situations: Copy-pasting attributes from two config examples; migrating from a bearer-token setup to an authentication-converter setup while leaving the old attribute in place.

Understand the failure class

Related errors


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

Appendix: source

Thrown at config/src/main/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParser.java:133

	public BeanDefinition parse(Element oauth2ResourceServer, ParserContext pc) {
		Element jwt = DomUtils.getChildElementByTagName(oauth2ResourceServer, Elements.JWT);
		Element opaqueToken = DomUtils.getChildElementByTagName(oauth2ResourceServer, Elements.OPAQUE_TOKEN);
		validateConfiguration(oauth2ResourceServer, jwt, opaqueToken, pc);
		if (jwt != null) {
			BeanDefinition jwtAuthenticationProvider = new JwtBeanDefinitionParser().parse(jwt, pc);
			this.authenticationProviders.add(new RuntimeBeanReference(
					pc.getReaderContext().registerWithGeneratedName(jwtAuthenticationProvider)));
		}
		if (opaqueToken != null) {
			BeanDefinition opaqueTokenAuthenticationProvider = new OpaqueTokenBeanDefinitionParser().parse(opaqueToken,
					pc);
			this.authenticationProviders.add(new RuntimeBeanReference(
					pc.getReaderContext().registerWithGeneratedName(opaqueTokenAuthenticationProvider)));
		}
		BeanMetadataElement bearerTokenResolver = getBearerTokenResolver(oauth2ResourceServer);
		BeanMetadataElement authenticationConverter = getAuthenticationConverter(oauth2ResourceServer);
		if (bearerTokenResolver != null && authenticationConverter != null) {
			throw new BeanDefinitionStoreException(
					"You cannot use bearer-token-ref and authentication-converter-ref in the same oauth2-resource-server element");
		}
		if (bearerTokenResolver == null && authenticationConverter == null) {
			authenticationConverter = new RootBeanDefinition(BearerTokenAuthenticationConverter.class);
		}
		BeanMetadataElement authenticationEntryPoint = getEntryPoint(oauth2ResourceServer);
		BeanDefinition requestMatcher = buildRequestMatcher(bearerTokenResolver, authenticationConverter);
		this.entryPoints.put(requestMatcher, authenticationEntryPoint);
		this.deniedHandlers.put(requestMatcher, this.accessDeniedHandler);
		this.ignoreCsrfRequestMatchers.add(requestMatcher);
		BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder
			.rootBeanDefinition(BearerTokenAuthenticationFilter.class);
		BeanMetadataElement authenticationManagerResolver = getAuthenticationManagerResolver(oauth2ResourceServer);
		filterBuilder.addConstructorArgValue(authenticationManagerResolver);
		filterBuilder.addPropertyValue(AUTHENTICATION_ENTRY_POINT, authenticationEntryPoint);
		filterBuilder.addPropertyValue("securityContextHolderStrategy",
				this.authenticationFilterSecurityContextHolderStrategy);

View on GitHub (pinned to 96852e8860)