spring-projects/spring-security · error · IllegalStateException

authorizationManagerFactory must be an instance of…

Error message

authorizationManagerFactory must be an instance of DefaultAuthorizationManagerFactory

What it means

SecurityEvaluationContextExtension allows customizing a role hierarchy/trust resolver by mutating its AuthorizationManagerFactory, but those mutators only work with the default implementation. When a custom AuthorizationManagerFactory was set, getDefaultAuthorizationManagerFactory throws IllegalStateException because it cannot safely apply the customization to an unknown implementation.

Solutions

  1. Remove the custom AuthorizationManagerFactory and keep the DefaultAuthorizationManagerFactory so the setters can be used.
  2. Apply the role hierarchy / trust resolver customization directly inside your custom factory implementation instead of via the setters.
  3. If both are needed, subclass or reconfigure so one mechanism owns the customization.

Example fix

// before
extension.setAuthorizationManagerFactory(customFactory);
extension.setRoleHierarchy(roleHierarchy); // throws
// after
SecurityEvaluationContextExtension extension = new SecurityEvaluationContextExtension();
extension.setRoleHierarchy(roleHierarchy); // default factory kept
Defensive patterns

Strategy: try-catch

Validate before calling

if (extension.getAuthorizationManagerFactory() != null
        && !(extension.getAuthorizationManagerFactory() instanceof DefaultAuthorizationManagerFactory)) {
    // customization setters unsupported: apply them inside the custom factory instead
}

Try / catch

try {
    extension.setRoleHierarchy(roleHierarchy);
} catch (IllegalStateException e) {
    log.warn("Custom AuthorizationManagerFactory in use; apply role hierarchy there", e);
}

Prevention

When it happens

Trigger: Setting a custom AuthorizationManagerFactory on SecurityEvaluationContextExtension, then calling setTrustResolver, setRoleHierarchy, or setDefaultRolePrefix.

Common situations: Spring Data + SpEL security setups where teams plug in a custom factory for role prefix handling and then also try to set a role hierarchy; combining beans from different configuration profiles.

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/2d0720af9ec2f6ac. Report an issue: GitHub.

Appendix: source

Thrown at data/src/main/java/org/springframework/security/data/repository/query/SecurityEvaluationContextExtension.java:185

	 * @param authorizationManagerFactory the {@link AuthorizationManagerFactory} to use.
	 * Cannot be null.
	 * @since 7.0
	 */
	public void setAuthorizationManagerFactory(AuthorizationManagerFactory<Object> authorizationManagerFactory) {
		Assert.notNull(authorizationManagerFactory, "authorizationManagerFactory cannot be null");
		this.authorizationManagerFactory = authorizationManagerFactory;
	}

	/**
	 * Allows accessing the {@link DefaultAuthorizationManagerFactory} for getting and
	 * setting defaults. This method will be removed in Spring Security 8.
	 * @return the {@link DefaultAuthorizationManagerFactory}
	 * @throws IllegalStateException if a different {@link AuthorizationManagerFactory}
	 * was already set
	 */
	private DefaultAuthorizationManagerFactory<Object> getDefaultAuthorizationManagerFactory() {
		if (!(this.authorizationManagerFactory instanceof DefaultAuthorizationManagerFactory<Object> defaultAuthorizationManagerFactory)) {
			throw new IllegalStateException(
					"authorizationManagerFactory must be an instance of DefaultAuthorizationManagerFactory");
		}

		return defaultAuthorizationManagerFactory;
	}

	/**
	 * Sets the {@link AuthenticationTrustResolver} to be used. Default is
	 * {@link AuthenticationTrustResolverImpl}. Cannot be null.
	 * @param trustResolver the {@link AuthenticationTrustResolver} to use
	 * @since 5.8
	 * @deprecated Use
	 * {@link #setAuthorizationManagerFactory(AuthorizationManagerFactory)} instead
	 */
	@Deprecated(since = "7.0")
	public void setTrustResolver(AuthenticationTrustResolver trustResolver) {
		Assert.notNull(trustResolver, "trustResolver cannot be null");
		getDefaultAuthorizationManagerFactory().setTrustResolver(trustResolver);

View on GitHub (pinned to 96852e8860)