quarkusio/quarkus · error · RuntimeException
Could not load exception mapper
Error message
Could not load exception mapper
What it means
RuntimeExceptionMapper loads the throwable classes listed in quarkus.rest.mappers (configured custom exception mappers) by name via loadThrowableClass. If Class.forName cannot find the configured class in the given classloader, initialization fails with this RuntimeException wrapping the ClassNotFoundException.
Source
Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/RuntimeExceptionMapper.java:65
mappers = new HashMap<>();
for (var i : mapping.effectiveMappers().entrySet()) {
mappers.put(loadThrowableClass(i.getKey(), classLoader), i.getValue());
}
blockingProblemPredicates = new ArrayList<>(mapping.blockingProblemPredicates);
nonBlockingProblemPredicate = new ArrayList<>(mapping.nonBlockingProblemPredicate);
unwrappedExceptions = new HashMap<>();
for (Map.Entry<String, ExceptionUnwrapStrategy> entry : mapping.getUnwrappedExceptions().entrySet()) {
Class<? extends Throwable> clazz = loadThrowableClass(entry.getKey(), classLoader);
ExceptionUnwrapStrategy strategy = entry.getValue();
unwrappedExceptions.put(clazz, strategy);
}
}
private static Class<? extends Throwable> loadThrowableClass(String className, ClassLoader classLoader) {
try {
return (Class<? extends Throwable>) Class.forName(className, false, classLoader);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Could not load exception mapper", e);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void mapException(Throwable throwable, ResteasyReactiveRequestContext context) {
Class<?> klass = throwable.getClass();
//we don't read WebApplicationException's thrown from the client as true 'WebApplicationException'
//we consider it a security risk to transparently pass on the result to the calling server
boolean isWebApplicationException = throwable instanceof WebApplicationException
&& !(throwable instanceof ResteasyReactiveClientProblem);
Response response = null;
if (isWebApplicationException) {
response = ((WebApplicationException) throwable).getResponse();
}
if (response != null && response.hasEntity()) {
context.setResult(response);
return;
}View on GitHub (pinned to e1c734241f)
Solutions
- Fix the fully-qualified mapper class name in your configuration to match an existing @Provider ExceptionMapper class.
- Ensure the class is on the runtime classpath (correct Maven/Gradle dependency scope, not excluded).
- If the class was renamed or removed, update or delete the stale configuration entry.
- Verify with `quarkus.log.category."...".level=DEBUG` or a classpath check that the class is packaged in the artifact.
Example fix
// application.properties before quarkus.rest.mappers.myMapper.class=com.example.OldMapper // after quarkus.rest.mappers.myMapper.class=com.example.NewExceptionMapper
Defensive patterns
Strategy: validation
Validate before calling
static void assertMapperPresent(String className, ClassLoader cl) {
try { cl.loadClass(className); }
catch (ClassNotFoundException e) { throw new IllegalStateException("Configured mapper class not found: " + className, e); }
} Type guard
boolean isConfiguredMapperLoadable(String fqcn, ClassLoader cl) {
try { return Throwable.class.isAssignableFrom(cl.loadClass(fqcn)); }
catch (ClassNotFoundException e) { return false; }
} Try / catch
try {
mapperRegistry.init();
} catch (RuntimeException e) {
if ("Could not load exception mapper".equals(e.getMessage())) {
log.error("Check quarkus.rest mapper config class names and dependency scopes", e.getCause());
}
throw e;
} Prevention
- Verify fully-qualified mapper class names in configuration against actual packages.
- Keep mapper classes in compile/runtime-scope dependencies.
- Update configuration when renaming or moving ExceptionMapper classes.
- Startup-validate configured class names in integration tests.
When it happens
Trigger: Configuring an exception mapper class name (e.g. quarkus.rest.* mapper config) that does not exist on the classpath at application start, so the mapper registry cannot be built.
Common situations: Typos in fully-qualified class names in configuration; renaming/moving a mapper class without updating config; mapper class in a dependency not packaged (optional/provided scope); class removed after a version upgrade.
Related errors
- Thread pool class not found: ${threadPoolClass}
- Unable to interpret path referenced in '" + RedisConfig.getP
- Unable to find file referenced in '" + RedisConfig.getProper
- Unable to load handled exception type ${i.getProvidedType()}
- The combination of '@${annotationName}' and '@ServerExceptio
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/22c3b76069bf2a85.
Report an issue: GitHub.