spring-projects/spring-security · error · IOException
No visible WebInvocationPrivilegeEvaluator instance could…
Error message
No visible WebInvocationPrivilegeEvaluator instance could be found in the application context. There must be at least one in order to support the use of URL access checks in 'authorize' tags.
What it means
The url attribute of the JSP 'authorize' tag needs a WebInvocationPrivilegeEvaluator to check whether the current user can access a URL. AbstractAuthorizeTag.getPrivilegeEvaluator() first checks a request attribute, then the ApplicationContext; if no WebInvocationPrivilegeEvaluator beans exist it throws this IOException.
Solutions
- Configure HTTP-based Spring Security (SecurityFilterChain with authorizeHttpRequests) so a WebInvocationPrivilegeEvaluator bean is registered in the context.
- Pre-populate the request attribute WebAttributes.WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE if you manage evaluators manually.
- Ensure the tag's ApplicationContext is the one containing the Security beans (context hierarchy/parent lookup).
- Replace the url attribute with an access expression (which uses the expression handler path) or move the check to Java authorization APIs.
- Verify spring-security-web/taglibs versions match so the privilege evaluator is auto-published.
Example fix
<!-- before -->
<sec:authorize url="/admin/**">...</sec:authorize>
<!-- with no security filter chain configured -->
<!-- after: ensure HTTP security is configured, or use access expression -->
<sec:authorize access="hasRole('ADMIN')">...</sec:authorize> Defensive patterns
Strategy: try-catch
Validate before calling
Map<String, WebInvocationPrivilegeEvaluator> wipes = ctx.getBeansOfType(WebInvocationPrivilegeEvaluator.class);
if (wipes.isEmpty()) {
throw new IllegalStateException("No WebInvocationPrivilegeEvaluator bean; configure HTTP security with authorizeHttpRequests");
} Try / catch
try { ... tag evaluation ... } catch (IOException ex) { if (ex.getMessage().contains("WebInvocationPrivilegeEvaluator")) { log.error("URL-based authorize tag requires an HTTP security configuration"); } throw ex; } Prevention
- Prefer access expressions over the url attribute when only method security is configured
- Ensure a SecurityFilterChain with authorizeHttpRequests exists to publish the privilege evaluator
- Set WebAttributes.WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE when managing evaluators manually
When it happens
Trigger: Using <sec:authorize url="/some/path"> (authorizeUsingUrlCheck) when ctx.getBeansOfType(WebInvocationPrivilegeEvaluator.class) is empty and no request attribute WebAttributes.WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE is set.
Common situations: Security configured only for method security (no FilterSecurityInterceptor/AuthorizationFilter, so no privilege evaluator bean is registered); using the tag without a security filter chain; older/newer Spring Security version mismatch where the WIP bean isn't auto-exposed; testing tags outside a full web setup.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- No visible WebSecurityExpressionHandler instance could be…
- A Bean named mvcHandlerMappingIntrospector of type…
- A Bean named mvcHandlerMappingIntrospector of type…
- A ReactiveSessionRegistry is needed for concurrent session…
- A ServerOneTimeTokenGenerationSuccessHandler is required to…
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/4502a62f9058e9c0.
Report an issue: GitHub.
Appendix: source
Thrown at taglibs/src/main/java/org/springframework/security/taglibs/authz/AbstractAuthorizeTag.java:219
if (FilterInvocation.class
.equals(GenericTypeResolver.resolveTypeArgument(handler.getClass(), SecurityExpressionHandler.class))) {
return handler;
}
}
throw new IOException("No visible WebSecurityExpressionHandler instance could be found in the application "
+ "context. There must be at least one in order to support expressions in JSP 'authorize' tags.");
}
private WebInvocationPrivilegeEvaluator getPrivilegeEvaluator() throws IOException {
WebInvocationPrivilegeEvaluator privEvaluatorFromRequest = (WebInvocationPrivilegeEvaluator) getRequest()
.getAttribute(WebAttributes.WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE);
if (privEvaluatorFromRequest != null) {
return privEvaluatorFromRequest;
}
ApplicationContext ctx = getApplicationContext();
Map<String, WebInvocationPrivilegeEvaluator> wipes = ctx.getBeansOfType(WebInvocationPrivilegeEvaluator.class);
if (wipes.isEmpty()) {
throw new IOException(
"No visible WebInvocationPrivilegeEvaluator instance could be found in the application "
+ "context. There must be at least one in order to support the use of URL access checks in 'authorize' tags.");
}
return (WebInvocationPrivilegeEvaluator) wipes.values().toArray()[0];
}
private ApplicationContext getApplicationContext() {
Object value = getRequest().getAttribute(WebAttributes.APPLICATION_CONTEXT_ATTRIBUTE);
if (value == null) {
return SecurityWebApplicationContextUtils.findRequiredWebApplicationContext(getServletContext());
}
if (value instanceof ApplicationContext context) {
return context;
}
throw new IllegalArgumentException("WebAttributes.APPLICATION_CONTEXT_ATTRIBUTE value must be of type "
+ "ApplicationContext, found type " + value.getClass());
}
View on GitHub (pinned to 96852e8860)