quarkusio/quarkus · error · IllegalArgumentException
Expression: '<part>' in the @PreAuthorize annotation on meth
Error message
Expression: '<part>' in the @PreAuthorize annotation on method '<method>' of class '<class>' is malformed
What it means
The processor supports @PreAuthorize expressions of the form principalUsername == #param (parameter equal-to / not-equal-to principal name). When a part of the expression matches the parameter-eq-principal-username shape but the regex capture fails, this generic malformed-expression IllegalArgumentException is thrown at build time (comment says 'should never happen').
Source
Thrown at extensions/spring-security/deployment/src/main/java/io/quarkus/spring/security/deployment/SpringSecurityProcessor.java:338
String value = instance.value().asString().trim();
String[] parts = { value };
if (value.toLowerCase().contains(" and ")) {
parts = value.split("(?i) and ");
} else if (value.toLowerCase().contains(" or ")) {
parts = value.split("(?i) or ");
}
/*
* this is essentially the same loop as in addSpringPreAuthorizeSecurityCheck but only deals with cases
* where beans need to be generated
*/
for (String part : parts) {
part = part.trim();
if (part.matches(PARAMETER_EQ_PRINCIPAL_USERNAME_REGEX)) {
Matcher matcher = PARAMETER_EQ_PRINCIPAL_USERNAME_PATTERN.matcher(part);
if (!matcher.find()) { // should never happen
throw SpringSecurityProcessorUtil.createGenericMalformedException(methodInfo, part);
}
ParameterNameAndIndex parameterNameAndIndex = getParameterNameAndIndexForPrincipalUserNameReference(
methodInfo,
matcher, part);
String propertyName = matcher.group(PARAMETER_EQ_PRINCIPAL_USERNAME_PROPERTY_ACCESSOR_MATCHER_GROUP);
if (propertyName != null) {
/*
* In this we need to call a getter method on the parameter. In order to do that we need to generate
* an accessor for that method (which is ensured to return type String since that is the type of the
* username).
*/
StringPropertyAccessorData stringPropertyAccessorData = StringPropertyAccessorData.from(
methodInfo, parameterNameAndIndex.getIndex(),
propertyName, index.getIndex(),
part);
View on GitHub (pinned to e1c734241f)
Solutions
- Rewrite the expression in the canonical supported form: principalUsername == #paramName or principalUsername != #paramName
- Remove odd whitespace/characters from the expression
- If the check persists on a simple expression, restructure as a bean-method check: @PreAuthorize("@authz.matches(#name)")
Example fix
// before
@PreAuthorize("#username==principal.username")
// after
@PreAuthorize("principalUsername == #username") Defensive patterns
Strategy: validation
Validate before calling
String expr = "principalUsername == #username";
java.util.regex.Pattern p = java.util.regex.Pattern.compile("(principalUsername|principal.username)\\s*(!?=)\\s*#\\w+");
if (!p.matcher(expr).find()) throw new IllegalArgumentException("Unsupported form: " + expr); Prevention
- Write parameter-vs-principal checks only in the documented form principalUsername == #param
- Avoid exotic whitespace or alternate spellings in expressions
- Prefer bean-method checks for anything beyond the supported patterns
When it happens
Trigger: An expression part matches PARAMETER_EQ_PRINCIPAL_USERNAME_REGEX after trimming, but the second, stricter matcher (PARAMETER_EQ_PRINCIPAL_USERNAME_PATTERN) fails to find groups in generateNecessarySupportClasses.
Common situations: Very rare — essentially an internal consistency failure; could surface with unusual whitespace or exotic characters in expressions that satisfy one regex but not the other.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Expression: '<expression>' in the @PreAuthorize annotation o
- 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
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/a89a6404b0389796.
Report an issue: GitHub.