quarkusio/quarkus · error · IllegalArgumentException
@Blocking referred to invalid worker name. ${workerName}
Error message
@Blocking referred to invalid worker name. ${workerName} What it means
@Blocking can name a specific worker pool, e.g. @Blocking("poolName"). If getWorker falls through — the named worker is neither a predefined executor nor a successfully created one — it throws IllegalArgumentException saying the annotation referred to an invalid worker name.
Source
Thrown at extensions/smallrye-reactive-messaging/runtime/src/main/java/io/quarkus/smallrye/reactivemessaging/runtime/QuarkusWorkerPoolRegistry.java:265
if (executor == null) {
WorkerPoolConfig config = workerConfig.get(workerName);
executor = executionHolder.vertx().createSharedWorkerExecutor(workerName,
config.maxConcurrency());
log.infof("Created worker pool named %s with concurrency of %d", workerName,
config.maxConcurrency());
workerExecutors.put(workerName, executor);
}
}
}
if (executor != null) {
return executor;
} else {
throw new RuntimeException("Failed to create Worker for " + workerName);
}
}
// Shouldn't get here
throw new IllegalArgumentException("@Blocking referred to invalid worker name. " + workerName);
}
public void defineWorker(String className, String method, String poolName, boolean virtualThread) {
Objects.requireNonNull(className, "className was empty");
Objects.requireNonNull(method, "Method was empty");
if (virtualThread) {
virtualThreadWorkers.add(poolName);
return;
}
if (!poolName.equals(Blocking.DEFAULT_WORKER_POOL)) {
// Validate @Blocking value is not empty, if set
if (Validation.isBlank(poolName)) {
throw getBlockingError(className, method, "value is blank or null");
}
Config config = ConfigProvider.getConfig();
// Validate @Blocking worker pool has configuration to define concurrencyView on GitHub (pinned to e1c734241f)
Solutions
- Fix the name in @Blocking to match an existing/defined worker pool.
- Use plain @Blocking to fall back to the default worker pool.
- Ensure the class/method carrying the pool definition still exists (it defines the pool named after the class+method).
- Check that generated defineWorker calls weren't skipped (e.g. wrong package/exclusion).
Example fix
// before
@Blocking("emial-pool")
void consume(String m) { ... }
// after
@Blocking("email-pool")
void consume(String m) { ... } Defensive patterns
Strategy: validation
Validate before calling
// Before using a named pool, verify a matching @Blocking method defines it: // grep -rn 'void .*' src/main/java --include='*.java' | grep -B1 '<MethodSignature>' // or ensure the name matches the defining class/method convention.
Prevention
- Keep pool names in shared constants referenced by both definition and @Blocking usage.
- Prefer plain @Blocking (default pool) when a named pool isn't strictly required.
- After renames, grep for the old pool name across the codebase.
When it happens
Trigger: @Blocking("someName") where 'someName' was never registered via defineWorker (deployment didn't create a matching @Blocking-annotated method pool) and no default executor matches.
Common situations: Typo in the @Blocking value; renaming the annotated method/pool in one place but not the other; using @Blocking("x") in a library where x is defined by an absent extension.
Related errors
- Failed to create Worker for ${workerName}
- Blocking gRPC client call made from the event loop. If the c
- @Transactional cannot start a JTA transaction within a react
- Invalid combination - a reactive route cannot use @Blocking
- @PermissionChecker annotation instance placed on the '%s' re
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/3bc7158372ce17ee.
Report an issue: GitHub.