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

  1. Rewrite the expression in the canonical supported form: principalUsername == #paramName or principalUsername != #paramName
  2. Remove odd whitespace/characters from the expression
  3. 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

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

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/a89a6404b0389796. Report an issue: GitHub.