apache/pulsar · error · PulsarClientException.InvalidConfigurationException

Can't use receive with timeout, if the queue size is 0

Error message

Can't use receive with timeout, if the queue size is 0

What it means

A consumer created with receiverQueueSize=0 (typically for readers or exactly-once / seek-heavy patterns) has no internal buffer to hold a message for the timeout-based receive to poll from, so receive(int timeout, TimeUnit unit) rejects this configuration with InvalidConfigurationException. Queue-size-0 consumers only deliver via async/internal paths, so the timed synchronous receive is unsupported by design.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/ConsumerBase.java:306

            return FutureUtil.failedFuture(new PulsarClientException.InvalidConfigurationException(
                    "Cannot use receive() when a listener has been set"));
        }
        try {
            verifyConsumerState();
        } catch (PulsarClientException e) {
            return FutureUtil.failedFuture(e);
        }
        return internalReceiveAsync();
    }

    protected abstract Message<T> internalReceive() throws PulsarClientException;

    protected abstract CompletableFuture<Message<T>> internalReceiveAsync();

    @Override
    public Message<T> receive(int timeout, TimeUnit unit) throws PulsarClientException {
        if (getCurrentReceiverQueueSize() == 0) {
            throw new PulsarClientException.InvalidConfigurationException(
                    "Can't use receive with timeout, if the queue size is 0");
        }
        if (listener != null) {
            throw new PulsarClientException.InvalidConfigurationException(
                    "Cannot use receive() when a listener has been set");
        }

        verifyConsumerState();
        return internalReceive(timeout, unit);
    }

    protected abstract Message<T> internalReceive(long timeout, TimeUnit unit) throws PulsarClientException;

    @Override
    public Messages<T> batchReceive() throws PulsarClientException {
        verifyBatchReceive();
        verifyConsumerState();
        return internalBatchReceive();

View on GitHub (pinned to 820761864e)

Solutions

  1. Set receiverQueueSize to at least 1 in the ConsumerBuilder/ReaderBuilder
  2. Use receive() or receiveAsync() instead of the timed receive(timeout, unit)
  3. Use Reader.readNext(timeout, unit), which is designed for reader-style consumption

Example fix

// before
Reader<String> r = client.newReader(Schema.STRING)
    .topic("t").readerName("rd")
    .receiverQueueSize(0).create();
Message<String> m = consumer.receive(1, TimeUnit.SECONDS);
// after
Reader<String> r = client.newReader(Schema.STRING)
    .topic("t").readerName("rd")
    .receiverQueueSize(0).create();
Message<String> m = r.readNext(1, TimeUnit.SECONDS);
Defensive patterns

Strategy: validation

Validate before calling

// check before using timed receive
// receiverQueueSize is fixed at build time; keep a flag from your builder
if (receiverQueueSize == 0) {
    throw new IllegalStateException("Timed receive() unsupported with receiverQueueSize=0; use Reader.readNext");
}

Type guard

boolean supportsTimedReceive(org.apache.pulsar.client.api.Consumer<T> c) {
    return ((ConsumerBase<T>) c).getCurrentReceiverQueueSize() > 0;
}

Try / catch

try {
    Message<T> msg = consumer.receive(1, TimeUnit.SECONDS);
} catch (PulsarClientException.InvalidConfigurationException e) {
    // queue size 0: switch to receive() / receiveAsync() / Reader.readNext
}

Prevention

When it happens

Trigger: Building a consumer with ConsumerBuilder.receiverQueueSize(0) (or ConsumerConfigurationData with receiverQueueSize 0, common for Readers) and then calling consumer.receive(timeout, unit).

Common situations: Using a Reader with receiverQueueSize=0 for low-latency tailing and then calling the timed receive; tuning queue size to 0 to 'reduce latency' without realizing timed receive stops working; shared consumer builder where queue size 0 is set conditionally.

Understand the failure class

Related errors


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