quarkusio/quarkus · error · java.lang.RuntimeException

Class '%s' was annotated with '@PermissionsAllowed', but no

Error message

Class '%s' was annotated with '@PermissionsAllowed', but no valid permission was provided

What it means

Identical to the method-level variant, but thrown when the @PermissionsAllowed annotation target is a CLASS and no valid permission was provided. Quarkus rejects class-level annotations that restrict nothing, because applying security to all methods with zero permissions cannot be satisfied.

Source

Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/PermissionSecurityChecks.java:640

                            final Set<String> actions = new HashSet<>();
                            actions.add(action);
                            permissionToActions.put(permissionNameKey, actions);
                        }
                    } else {
                        if (!permissionToActions.containsKey(permissionNameKey)) {
                            permissionToActions.put(permissionNameKey, new HashSet<>());
                        }
                    }
                }
            }

            if (permissionToActions.isEmpty()) {
                if (annotationTarget.kind() == AnnotationTarget.Kind.METHOD) {
                    throw new RuntimeException(String.format(
                            "Method '%s' was annotated with '@PermissionsAllowed', but no valid permission was provided",
                            annotationTarget.asMethod().name()));
                } else {
                    throw new RuntimeException(String.format(
                            "Class '%s' was annotated with '@PermissionsAllowed', but no valid permission was provided",
                            annotationTarget.asClass().name()));
                }
            }

            // permissions specified via @PermissionsAllowed has 'one of' relation, therefore we put them in one list
            final List<PermissionKey> orPermissions = new ArrayList<>();
            final String[] params = instance.value("params") == null ? new String[] { PermissionsAllowed.AUTODETECTED }
                    : instance.value("params").asStringArray();
            final Type classType = getPermissionClass(instance);
            final boolean inclusive = instance.value("inclusive") != null && instance.value("inclusive").asBoolean();

            if (inclusive && foundPermissionChecker) {
                // @PermissionsAllowed({ "read", "read:all", "read:it", "write" } && @PermissionChecker("read")
                // require @PermissionChecker for all 'read:action' because determining expected behavior would be too
                // complex; similarly for @PermissionChecker("read:all") require 'read' and 'read:it' have checker as well
                List<PermissionNameAndChecker> checkerPermissions = permissionToActions.keySet().stream()
                        .filter(k -> k.checker != null).toList();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add at least one valid permission to the class-level @PermissionsAllowed, e.g. @PermissionsAllowed("admin").
  2. Remove the annotation if class-wide permission enforcement is not intended.
  3. If different permissions per method are needed, move @PermissionsAllowed from the class to individual methods.

Example fix

// before
@PermissionsAllowed({})
public class AdminService { ... }

// after
@PermissionsAllowed("admin")
public class AdminService { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Class-level check: ensure the shared permission constant array is non-empty
assert permissionValues != null && permissionValues.length > 0 : "class-level @PermissionsAllowed needs values";

Prevention

When it happens

Trigger: Annotating a class with @PermissionsAllowed using an empty value array or values that all fail parsing, leaving permissionToActions empty for the class.

Common situations: Copy-pasted class-level annotation with placeholder values; constants array emptied by refactor; values relying on an unsupported expression form so everything is dropped.

Related errors


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