spring-projects/spring-security · error · JspException

Found incorrect number of instances in application context…

Error message

Found incorrect number of  instances in application context - you must have only have one!

What it means

AccessControlListTag.getBeanOfType() looks up exactly one bean of the required ACL type (e.g. AclService or SidRetrievalStrategy) in the application context. If more than one bean of that type exists, the tag cannot decide which to use and throws JspException. Zero beans returns null (deferred to defaults); exactly one is used.

Solutions

  1. Remove or rename the duplicate beans so exactly one bean of the required ACL type exists
  2. Mark the intended bean as @Primary or set autowire-candidate=false on the others (if the lookup honors it, otherwise delete)
  3. Qualify/limit component-scan packages so only one AclService is registered

Example fix

// before
@Bean AclService aclService() { ... }
@Bean AclService backupAclService() { ... } // duplicate
// after
@Bean AclService aclService() { ... }
// (delete or exclude backupAclService)
Defensive patterns

Strategy: validation

Validate before calling

Map<String, AclService> beans = ctx.getBeansOfType(AclService.class);
if (beans.size() > 1) throw new IllegalStateException(
    "Expected 1 AclService bean, found " + beans.size() + ": " + beans.keySet());

Try / catch

try {
    pageContext.getAttributes(); // render path
} catch (JspException e) {
    if (e.getMessage().contains("incorrect number of")) {
        log.error("Duplicate ACL beans — check getBeansOfType counts", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A JSP page using <sec:accesscontrollist> is rendered while the Spring application context contains two or more beans implementing the type required by the ACL tag (typically LookupStrategy/AclService or the SidStrategy), and initializeIfRequired() runs the lookup.

Common situations: Defining a primary AclService plus a test/backup one; component scanning pulls in a second AclService bean from a shared library; duplicate bean definitions across XML and @Configuration.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at taglibs/src/main/java/org/springframework/security/taglibs/authz/AccessControlListTag.java:179

			SecurityContextHolderStrategy strategy = this.applicationContext
				.getBean(SecurityContextHolderStrategy.class);
			this.securityContextHolderStrategy = strategy;
		}
	}

	private <T> @Nullable T getBeanOfType(Class<T> type) throws JspException {
		Map<String, T> map = this.applicationContext.getBeansOfType(type);
		for (ApplicationContext context = this.applicationContext.getParent(); context != null; context = context
			.getParent()) {
			map.putAll(context.getBeansOfType(type));
		}
		if (map.isEmpty()) {
			return null;
		}
		if (map.size() == 1) {
			return map.values().iterator().next();
		}
		throw new JspException("Found incorrect number of " + type.getSimpleName() + " instances in "
				+ "application context - you must have only have one!");
	}

	public void setDomainObject(Object domainObject) {
		this.domainObject = domainObject;
	}

	public void setHasPermission(String hasPermission) {
		this.hasPermission = hasPermission;
	}

	public void setVar(String var) {
		this.var = var;
	}

}

View on GitHub (pinned to 96852e8860)