spring-projects/spring-security · error · IllegalArgumentException
Failed to evaluate expression '{expressionString}'
Error message
Failed to evaluate expression '{expressionString}' What it means
ExpressionUtils.evaluateAsBoolean wraps Spring Expression EvaluationException into IllegalArgumentException when a SpEL security expression cannot be evaluated at all — malformed SpEL, unknown methods/properties, wrong argument types, or exceptions thrown inside the expression. The original EvaluationException is preserved as the cause.
Source
Thrown at core/src/main/java/org/springframework/security/access/expression/ExpressionUtils.java:38
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
public final class ExpressionUtils {
private ExpressionUtils() {
}
public static boolean evaluateAsBoolean(Expression expr, EvaluationContext ctx) {
try {
Boolean result = expr.getValue(ctx, Boolean.class);
if (result == null) {
throw new IllegalArgumentException(
"Expression was null but expected boolean result '" + expr.getExpressionString() + "'");
}
return result;
}
catch (EvaluationException ex) {
throw new IllegalArgumentException("Failed to evaluate expression '" + expr.getExpressionString() + "'",
ex);
}
}
}
View on GitHub (pinned to 96852e8860)
Solutions
- Read the cause (EvaluationException) attached to this IllegalArgumentException — it names the exact SpEL problem
- Verify every bean/method/property referenced in the expression exists with a compatible signature
- Test the expression in isolation: ExpressionParser.parseExpression(expr).getValue(ctx, Boolean.class)
- Fix SpEL syntax; for null-able paths use ?. and Elvis ?: operators
Example fix
// before
@PreAuthorize("@permissionService.hasPermisson(#id)") // typo in method
// after
@PreAuthorize("@permissionService.hasPermission(#id)") Defensive patterns
Strategy: try-catch
Validate before calling
new SpelExpressionParser().parseExpression(expressionString); // parse-check at startup
Type guard
null
Try / catch
try { ExpressionUtils.evaluateAsBoolean(expr, ctx); }
catch (IllegalArgumentException e) {
log.warn("SpEL evaluation failed: {}", e.getCause(), e);
throw new AccessDeniedException("Invalid security expression");
} Prevention
- Startup-test all @PreAuthorize expressions by evaluating them with a mock context
- Keep bean/method names in expressions in sync with refactors (IDE search)
- Use constants or meta-annotations instead of hand-written duplicate SpEL
- Always inspect the cause chain (EvaluationException) for the root problem
When it happens
Trigger: Any @PreAuthorize/@PostAuthorize/@PreFilter expression whose SpEL evaluation throws: referencing a non-existent bean or method, typo in a property (hasRole vs hasAuthority misuse), wrong parameter types, or el variables not present in the EvaluationContext.
Common situations: Typos in bean names inside @PreAuthorize; method signature changes breaking existing security expressions; SpEL syntax errors after editing annotations; missing SecurityExpressionRoot context when evaluating expressions manually.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Expression was null but expected boolean result '{expression
- Access is denied
- Security interception failed due to: %s; secure object: %s;
- Security authorization failed due to: %s; authenticated prin
- Access is denied
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/3566f8652f8623b0.
Report an issue: GitHub.