apache/pulsar · error · IllegalArgumentException

Receiver queue size should be >= zero

Error message

Receiver queue size should be >= zero

What it means

Within each entry of FunctionConfig.inputSpecs (InputSpec map keyed by topic), receiverQueueSize must be zero or a positive number. A negative value cannot be honored by the consumer subscription and throws IllegalArgumentException('Receiver queue size should be >= zero') while iterating inputSpecs in doCommonChecks.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:919

        }
        if (!isEmpty(functionConfig.getGo()) && !org.apache.pulsar.common.functions.Utils
                .isFunctionPackageUrlSupported(functionConfig.getGo())
                && functionConfig.getGo().startsWith(BUILTIN)) {
            String filename = functionConfig.getGo();
            if (filename.contains("..")) {
                throw new IllegalArgumentException("Invalid filename: " + filename);
            }

            if (!new File(filename).exists()) {
                throw new IllegalArgumentException("The supplied go file does not exist");
            }
        }

        if (functionConfig.getInputSpecs() != null) {
            functionConfig.getInputSpecs().forEach((topicName, conf) -> {
                // receiver queue size should be >= 0
                if (conf.getReceiverQueueSize() != null && conf.getReceiverQueueSize() < 0) {
                    throw new IllegalArgumentException(
                        "Receiver queue size should be >= zero");
                }

                if (conf.getCryptoConfig() != null && isBlank(conf.getCryptoConfig().getCryptoKeyReaderClassName())) {
                    throw new IllegalArgumentException(
                            "CryptoKeyReader class name required");
                }
                if (conf.getMessagePayloadProcessorConfig() != null && isBlank(
                        conf.getMessagePayloadProcessorConfig().getClassName())) {
                    throw new IllegalArgumentException(
                            "MessagePayloadProcessor class name required");
                }
            });
        }

        if (functionConfig.getProducerConfig() != null
                && functionConfig.getProducerConfig().getCryptoConfig() != null) {
            if (isBlank(functionConfig.getProducerConfig().getCryptoConfig().getCryptoKeyReaderClassName())) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Set receiverQueueSize to 0 or a positive value (e.g. 0 to disable buffering, 1000 for a larger buffer)
  2. Remove the explicit receiverQueueSize so the default is used
  3. Clamp/validate the value before building InputSpecs: Math.max(0, configuredSize)
  4. Fix the upstream config source (YAML/JSON/env) that produced the negative number

Example fix

// before
InputSpec spec = new InputSpec().setReceiverQueueSize(-1);
// after
InputSpec spec = new InputSpec().setReceiverQueueSize(1000); // must be >= 0
Defensive patterns

Strategy: validation

Validate before calling

conf.getInputSpecs().forEach((topic, spec) -> {
    Integer q = spec.getReceiverQueueSize();
    if (q != null && q < 0) {
        spec.setReceiverQueueSize(Math.max(0, q)); // or throw your own clear error
    }
});

Type guard

boolean hasValidReceiverQueueSizes(FunctionConfig c) {
    return c.getInputSpecs() == null || c.getInputSpecs().values().stream()
        .allMatch(s -> s.getReceiverQueueSize() == null || s.getReceiverQueueSize() >= 0);
}

Try / catch

try {
    admin.functions().createFunction(conf);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Receiver queue size")) {
        conf.getInputSpecs().values().forEach(s ->
            { if (s.getReceiverQueueSize() != null && s.getReceiverQueueSize() < 0) s.setReceiverQueueSize(0); });
        admin.functions().createFunction(conf);
    } else throw e;
}

Prevention

When it happens

Trigger: Creating/updating a function whose InputSpec for any input topic has setReceiverQueueSize(-1) (or any negative Integer), e.g. conf.setInputSpecs(Map.of("topic", new InputSpec().setReceiverQueueSize(-1))).

Common situations: Using -1 as a sentinel meaning 'unbounded/default' (not valid here); arithmetic or config-parsing bugs producing negative sizes; copying consumer configs where a different library accepted negatives; YAML/JSON edits that introduce a minus sign.

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 apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/310b088f2ef414a2. Report an issue: GitHub.