apache/pulsar · error · IllegalArgumentException

callbackThreads must be >= 1

Error message

callbackThreads must be >= 1

What it means

ConnectionPolicy requires callbackThreads >= 1 because callbackThreads sizes the executor that runs the client's user-facing callbacks and completion handlers; with zero or negative threads no callback could ever execute. The constructor throws IllegalArgumentException for smaller values.

Source

Thrown at pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/ConnectionPolicy.java:70

                             Duration keepAliveInterval,
                             Duration connectionMaxIdleTime,
                             int ioThreads,
                             int callbackThreads,
                             String proxyServiceUrl,
                             ProxyProtocol proxyProtocol,
                             BackoffPolicy connectionBackoff) {
        Objects.requireNonNull(connectionTimeout, "connectionTimeout must not be null");
        Objects.requireNonNull(keepAliveInterval, "keepAliveInterval must not be null");
        Objects.requireNonNull(connectionMaxIdleTime, "connectionMaxIdleTime must not be null");
        Objects.requireNonNull(connectionBackoff, "connectionBackoff must not be null");
        if (connectionsPerBroker < 1) {
            throw new IllegalArgumentException("connectionsPerBroker must be >= 1");
        }
        if (ioThreads < 1) {
            throw new IllegalArgumentException("ioThreads must be >= 1");
        }
        if (callbackThreads < 1) {
            throw new IllegalArgumentException("callbackThreads must be >= 1");
        }
        this.connectionTimeout = connectionTimeout;
        this.connectionsPerBroker = connectionsPerBroker;
        this.enableTcpNoDelay = enableTcpNoDelay;
        this.keepAliveInterval = keepAliveInterval;
        this.connectionMaxIdleTime = connectionMaxIdleTime;
        this.ioThreads = ioThreads;
        this.callbackThreads = callbackThreads;
        this.proxyServiceUrl = proxyServiceUrl;
        this.proxyProtocol = proxyProtocol;
        this.connectionBackoff = connectionBackoff;
    }

    /**
     * @return the maximum duration to wait for a TCP connection to a broker
     */
    public Duration connectionTimeout() {
        return connectionTimeout;

View on GitHub (pinned to 820761864e)

Solutions

  1. Set callbackThreads to a positive number appropriate for your workload (e.g. number of cores).
  2. Clamp computed values with Math.max(1, value) before passing them.
  3. Omit the call to accept the library default.

Example fix

// before
ConnectionPolicy cp = ConnectionPolicy.builder()
    .callbackThreads(0) // IllegalArgumentException
    .build();

// after
ConnectionPolicy cp = ConnectionPolicy.builder()
    .callbackThreads(Runtime.getRuntime().availableProcessors())
    .build();
Defensive patterns

Strategy: validation

Validate before calling

int threads = Math.max(1, cfg.callbackThreads());
ConnectionPolicy cp = ConnectionPolicy.builder().callbackThreads(threads).build();

Type guard

static boolean isValidCallbackThreads(int v) { return v >= 1; }

Try / catch

try {
    cp = ConnectionPolicy.builder().callbackThreads(threads).build();
} catch (IllegalArgumentException e) {
    log.warn("Invalid callbackThreads, using default", e);
    cp = ConnectionPolicy.builder().build();
}

Prevention

When it happens

Trigger: Calling ConnectionPolicy.builder().callbackThreads(0) or negative; deriving the count from config or a formula that can produce 0, similar to ioThreads sizing errors.

Common situations: Copy-pasting a tuning block with callbackThreads(0) intending 'use default'; dividing CPU count in containers with low CPU limits; sentinel-based config parsing mapping 'unset' to 0.

Understand the failure class

Background: "Invalid configuration value" and "Unsupported/Unknown setting value" errors: why libraries reject your config strings, numbers, and types — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/d853f7c6a2be4881. Report an issue: GitHub.