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

  1. Set the configured limit to a positive integer (>= 1).
  2. Remove the config override to fall back to the default limit.
  3. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/e0f13d5bfc5d6c45. Report an issue: GitHub.