quarkusio/quarkus · error · RuntimeException
Unable to load class '%s' for creating permission
Error message
Unable to load class '%s' for creating permission
What it means
SecurityCheckRecorder.loadClass() loads a permission class by name via the thread contextClassLoader at runtime. If the class is not found it wraps the ClassNotFoundException in a RuntimeException. This happens during recording/registration of permission-based security checks when a configured permission class name cannot be resolved.
Source
Thrown at extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityCheckRecorder.java:373
public SecurityCheckStorage create(RuntimeValue<SecurityCheckStorageBuilder> builder) {
return builder.getValue().create();
}
public void resolveRolesAllowedConfigExpRoles() {
if (!configExpRolesAllowedChecks.isEmpty()) {
for (SupplierRolesAllowedCheck configExpRolesAllowedCheck : configExpRolesAllowedChecks) {
configExpRolesAllowedCheck.resolveAllowedRoles();
}
configExpRolesAllowedChecks.clear();
}
}
private Class<?> loadClass(String className) {
try {
return Thread.currentThread().getContextClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unable to load class '" + className + "' for creating permission", e);
}
}
public void registerDefaultSecurityCheck(RuntimeValue<SecurityCheckStorageBuilder> builder, SecurityCheck securityCheck) {
builder.getValue().registerDefaultSecurityCheck(securityCheck);
}
public Supplier<SecurityConstrainer> createSecurityConstrainer(Supplier<Map<String, Object>> additionalEventPropsSupplier) {
return new Supplier<SecurityConstrainer>() {
@Override
public SecurityConstrainer get() {
var container = Arc.container();
var beanManager = container.beanManager();
var eventPropsSupplier = additionalEventPropsSupplier == null ? new Supplier<Map<String, Object>>() {
@Override
public Map<String, Object> get() {
return Map.of();
}View on GitHub (pinned to e1c734241f)
Solutions
- Fix the fully-qualified class name in config or annotation — verify spelling and package.
- Add the dependency containing the Permission class to the runtime (non-test, non-optional) scope.
- Rebuild the application after adding the dependency so the class is packaged.
- If using Quarkus, ensure the class is not in a deployment-only module; runtime classes must be in a runtime artifact.
Example fix
// before (application.properties) quarkus.security.permissions.perm1.class=com.acme.security.MyPermisson // after (typo fixed) quarkus.security.permissions.perm1.class=com.acme.security.MyPermission
Defensive patterns
Strategy: validation
Validate before calling
try {
Class.forName("com.acme.security.MyPermission", false,
Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Permission class missing from runtime classpath", e);
} Try / catch
try {
securedService.invoke();
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Unable to load class")) {
log.error("Check quarkus.security.permissions.* class names and dependencies", e);
}
} Prevention
- Use fully-qualified names copied from the class declaration, never hand-typed
- Keep permission classes in runtime-scope dependencies
- Grep application.properties for permission class names after refactors
- Run a smoke test that touches each configured permission at startup
When it happens
Trigger: quarkus.security.permissions.<name>.class or a @PermissionsAllowed permission class name refers to a class missing from the runtime application classpath, or a typo in the fully-qualified name.
Common situations: Typo in fully-qualified class name in configuration; permission class lives in a module/dependency not included in the build; class renamed after a refactor or version upgrade; class only present in a test scope dependency.
Related errors
- Can't load class: <settingStringValue>
- Cannot load task class: {taskClass}
- Cannot load async task class: {taskClass}
- Cannot load skip predicate class: {taskClass}
- Unable to load handled exception type ${i.getProvidedType()}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/01f2cd05683707ef.
Report an issue: GitHub.