quarkusio/quarkus · error · IllegalStateException
Resource being loaded more than once:
Error message
Resource being loaded more than once:
What it means
ClassLoaderLimiter tracks resources registered as atMostOnceResources and throws this IllegalStateException the second time any classloader attempts to load them. It is an assertion mechanism that guarantees a resource is opened at most once across all monitored classloaders.
Source
Thrown at independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/ClassLoaderLimiter.java:50
@Override
public void openResourceStream(String resourceName, String classLoaderName) {
Objects.requireNonNull(resourceName);
Objects.requireNonNull(classLoaderName);
if (traceAllResourceLoad) {
System.out.println("Opening resource: " + resourceName);
}
if (onHitPrintStacktrace.contains(resourceName)) {
final RuntimeException e = new RuntimeException("Tracing load of resource: " + resourceName);
e.printStackTrace();
}
if (vetoedResources.contains(resourceName)) {
throw new IllegalStateException(
"Attempted to load vetoed resource '" + resourceName + "' from classloader " + classLoaderName);
}
if (atMostOnceResources.contains(resourceName)) {
final String previousLoadEvent = atMostOnceResourcesLoaded.put(resourceName, classLoaderName);
if (previousLoadEvent != null) {
throw new IllegalStateException("Resource being loaded more than once: " + resourceName + ".\n" +
"Attempted load by " + classLoaderName + ", recorded previous load by " + previousLoadEvent);
}
}
if (resourceName.endsWith(".class")) {
//Skip further tracking on classes as it would create unnecessary noise
return;
}
final String previousLoad = allResourcesLoaded.put(resourceName, classLoaderName);
if (previousLoad != null) {
//This diagnostic has no flag, as it's generally useful, doesn't throw exceptions, and should
//generally not log much at all.
System.out.println(
"Resource loaded multiple times: " + resourceName + ". Currently being loaded by " + classLoaderName +
", previous loaded by " + previousLoad);
}
}
@OverrideView on GitHub (pinned to e1c734241f)
Solutions
- Introduce caching so the resource is read once and reused (e.g. static/holder caching in the loading code).
- Identify the two loading classloaders from the message and unify the loading path in one of them.
- If duplicate loads are acceptable now, drop the atMostOnceResource registration from the limiter builder.
Example fix
// before
try (InputStream in = cl.getResourceAsStream("app.properties")) { ... } // called repeatedly
// after
private static final Properties PROPS = loadOnce("app.properties"); Defensive patterns
Strategy: validation
Validate before calling
// ensure single read: cache resource contents at first access private static final Map<String, byte[]> CACHE = new ConcurrentHashMap<>(); byte[] data = CACHE.computeIfAbsent(name, n -> readOnce(n));
Try / catch
try { open(path); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Resource being loaded more than once")) { log.error("Duplicate load: {}", e.getMessage()); } else { throw e; } } Prevention
- Cache resource contents instead of re-reading from the classloader.
- Centralize resource access in one utility per classloader hierarchy.
- Register at-most-once expectations only for resources you control.
When it happens
Trigger: openResourceStream is called for a resource listed in atMostOnceResources that already has a recorded load event in atMostOnceResourcesLoaded (put returns a non-null previous event).
Common situations: Tests verifying single-load invariants for config/bootstrap resources; failures when caching is missing and the same resource is re-read, or when two subsystems independently read the same resource.
Related errors
- Attempted to load vetoed resource '
- Attempted to load vetoed class '
- resource listed multiple times as never loaded:
- Failed to load steps from %s
- The class (${name}) cannot be created during deployment.
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/8a76401224d2eb5e.
Report an issue: GitHub.