quarkusio/quarkus · error · IllegalStateException

CDI bean '%s' is not available, but it is required by the @P

Error message

CDI bean '%s' is not available, but it is required by the @PermissionChecker method

What it means

PermissionChecker beans referenced by @PermissionChecker-generated QuarkusPermission instances are looked up lazily through Arc at authorization time. If the CDI bean cannot be resolved (bean not discovered or not registered), getBeanInstanceHandle throws IllegalStateException naming the bean class.

Source

Thrown at extensions/security/runtime/src/main/java/io/quarkus/security/runtime/QuarkusPermission.java:128

        return "";
    }

    @Override
    public final boolean equals(Object object) {
        return this == object;
    }

    @Override
    public final int hashCode() {
        return Objects.hash(toString());
    }

    private InstanceHandle<T> getBeanInstanceHandle() {
        if (bean == null) {
            // this is done lazily because permissions without extra constructor arguments are created before Arc is ready
            bean = Arc.container().instance(getBeanClass());
            if (!bean.isAvailable()) {
                throw new IllegalStateException(
                        "CDI bean '%s' is not available, but it is required by the @PermissionChecker method"
                                .formatted(getBeanClass()));
            }
        }
        return bean;
    }

    // used by generated subclasses
    protected static Uni<Boolean> accessDenied() {
        return Uni.createFrom().item(false);
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Annotate the class owning the @PermissionChecker method with a bean-defining annotation (@ApplicationScoped or @Singleton).
  2. Verify the bean is not excluded by quarkus.arc.exclude-packages / quarkus.index-dependencies scoping and that the package is indexed.
  3. Run with quarkus.arc.fail-non-init or inspect the build log for bean discovery warnings; confirm Arc.container().instance(MyBean.class).isAvailable() is true.

Example fix

// before
public class UserPermissionChecker {
    @PermissionChecker("delete:user")
    boolean canDelete(...) { ... }
}
// after
@ApplicationScoped
public class UserPermissionChecker {
    @PermissionChecker("delete:user")
    boolean canDelete(...) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

// startup sanity check
InstanceHandle<MyBean> h = Arc.container().instance(MyBean.class);
if (!h.isAvailable()) throw new IllegalStateException("MyBean not discovered: add a bean-defining annotation");

Try / catch

try {
    boolean ok = permissionChecker.check(auth);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("is not available")) {
        // bean discovery issue: log and fail deployment in dev
    } else throw e;
}

Prevention

When it happens

Trigger: At authorization time, the bean class backing a @PermissionChecker method is not an available CDI bean: missing @ApplicationScoped or other bean-defining annotation, wrong package excluded by quarkus.arc exclude, or the class was moved/refactored.

Common situations: Forgetting a bean-defining annotation on the class containing the @PermissionChecker method; beans-only build (quarkus.arc.legacy-... off) skipping unannotated classes; tests where the bean package is not scanned.

Related errors


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