quarkusio/quarkus · error · IllegalStateException
Currently expressions containing both logical 'and' / 'or' a
Error message
Currently expressions containing both logical 'and' / 'or' are not supported. Offending expression is <value>' in the @PreAuthorize annotation on method '<method>' of class '<class>
What it means
Quarkus's Spring Security expression subset cannot evaluate an expression containing both logical 'and' and 'or' operators. addSpringPreAuthorizeSecurityCheck detects both in the @PreAuthorize value and throws this IllegalStateException at build time. (Note the message has an unbalanced quote — cosmetic.)
Source
Thrown at extensions/spring-security/deployment/src/main/java/io/quarkus/spring/security/deployment/SpringSecurityProcessor.java:427
MethodInfo methodInfo = entry.getKey();
String value = instance.value().asString().trim();
/*
* TODO: this serves fine for most purposes but a full-blown solution will need a proper parser
*/
boolean containsAnd = false;
boolean containsOr = false;
String lowercaseValue = value.toLowerCase();
if (lowercaseValue.contains(" or ")) {
containsOr = true;
}
if (lowercaseValue.contains(" and ")) {
containsAnd = true;
}
if (containsAnd && containsOr) {
throw new IllegalStateException(
"Currently expressions containing both logical 'and' / 'or' are not supported. Offending expression is "
+ value + "' in the @PreAuthorize annotation on method '" + methodInfo.name()
+ "' of class '" + methodInfo.declaringClass());
}
String[] parts = { value };
if (containsAnd) {
parts = value.split("(?i) and ");
} else if (containsOr) {
parts = value.split("(?i) or ");
}
List<SecurityCheck> securityChecks = new ArrayList<>(parts.length);
for (String part : parts) {
part = part.trim();
if (part.equals("permitAll()")) {
securityChecks.add(securityCheckRecorder.permitAll());View on GitHub (pinned to e1c734241f)
Solutions
- Split the logic: keep the simpler conditions in @PreAuthorize and move the compound decision into a public boolean bean method invoked as @PreAuthorize("@authz.canAccess(#x)")
- Use only 'and' or only 'or' in the expression if it can be restructured (single operator forms are supported)
- Drop parentheses-dependent logic entirely and evaluate it in application code or a custom SecurityCheck
Example fix
// before
@PreAuthorize("hasRole('admin') and #user == principalUsername or isAnonymous()")
// after
@PreAuthorize("@authz.canAccess(#user)") // public boolean canAccess(String user) { ... } Defensive patterns
Strategy: validation
Validate before calling
String v = "hasRole('admin') and hasRole('user')";
String lc = v.toLowerCase();
if (lc.contains(" and ") && lc.contains(" or "))
throw new IllegalStateException("Both 'and' and 'or' unsupported: " + v); Prevention
- Use only one logical operator per @PreAuthorize expression
- Move compound boolean logic into a boolean bean method
- Add a unit/arch test that scans @PreAuthorize values for mixed operators
When it happens
Trigger: An expression like "hasRole('admin') and hasRole('user') or isAuthenticated()" — where the lowercased value contains both " and " and " or " — triggers the check.
Common situations: Porting complex Spring SpEL security rules unchanged; combining role checks with other conditions in one annotation; writing compound authorization rules.
Related errors
- Parameter with index <i> of method '<beanMethod>' found in e
- Parameter with index <i> of method '<beanMethod>' found in e
- Could not match a unique method name '<methodName>' for bean
- Could not find a public, boolean returning method named '<me
- Expression: '<expression>' in the @PreAuthorize annotation o
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4ff2895d332d344d.
Report an issue: GitHub.