quarkusio/quarkus · error · IllegalArgumentException
Limit must be a positive integer:
Error message
Limit must be a positive integer:
What it means
ConcurrencyLimiter throttles concurrent receiver executions with a bounded permit count. A limit of zero or negative would deadlock every invocation, so the constructor validates it eagerly and throws IllegalArgumentException.
Source
Thrown at extensions/signals/runtime/src/main/java/io/quarkus/signals/runtime/impl/ConcurrencyLimiter.java:20
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import org.jboss.logging.Logger;
class ConcurrencyLimiter {
private static final Logger LOG = Logger.getLogger(ConcurrencyLimiter.class);
private final int limit;
private final AtomicInteger running;
private final Queue<Action> queue;
ConcurrencyLimiter(int limit) {
if (limit <= 0) {
throw new IllegalArgumentException(
"Limit must be a positive integer: " + limit);
}
this.limit = limit;
this.running = new AtomicInteger();
this.queue = new ConcurrentLinkedQueue<>();
}
void run(Runnable task, Consumer<Throwable> onError) {
queue.offer(new Action(task, onError));
LOG.debugf("Queue action [running=%s, limit=%s]", running, limit);
tryDrain();
}
/**
* Signals that a previously started action has finished. Must be called exactly once per started action, and must not be
* called synchronously inside the action's {@link Runnable#run()} — doing so causes recursive {@link #tryDrain()} calls
* whose stack depth equals the queue size.
*/View on GitHub (pinned to e1c734241f)
Solutions
- Set the configured limit to a positive integer (>= 1).
- Remove the config override to fall back to the default limit.
- If you intended unlimited concurrency, use the non-limited executor instead of a 0 limit.
Example fix
// before quarkus.signal.concurrency-limit=0 // after quarkus.signal.concurrency-limit=10
Defensive patterns
Strategy: validation
Validate before calling
int limit = Integer.parseInt(cfg.limit());
if (limit <= 0) throw new IllegalArgumentException("concurrency limit must be positive, got " + limit); Prevention
- Never configure 0 or negative limits expecting 'unlimited'.
- Validate config in tests with @ConfigMapping defaults.
- Document the accepted range for the limit property.
When it happens
Trigger: Constructing ConcurrencyLimiter with limit <= 0, typically from a misconfigured limit property (0, negative, or a failed parse defaulting oddly).
Common situations: Setting a config value like quarkus.signal...limit=0 to mean 'unlimited' (unsupported) or typos such as '-1'.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Unrecognized dependency flag '<trimmed>'. Supported flags: O
- Parameter 'mode' was set to '<mode>' while expected one of '
- Parameter 'mode' was set to '<mode>' while expected one of '
- Parameter 'mode' was set to '<mode>' while expected one of '
- Manifest entry name ${key} is invalid. " characters are not
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e0f13d5bfc5d6c45.
Report an issue: GitHub.