apache/pulsar · error · IllegalArgumentException

Sink parallelism must be a positive number

Error message

Sink parallelism must be a positive number

What it means

When the sink config specifies a parallelism, it must be strictly positive. validateAndExtractDetails throws IllegalArgumentException if parallelism is null-safe-checked but <= 0 (i.e. 0 or negative values passed explicitly).

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java:447

        Collection<String> allInputs = collectAllInputTopics(sinkConfig);
        if (allInputs.isEmpty()) {
            throw new IllegalArgumentException("Must specify at least one topic of input via topicToSerdeClassName, "
                    + "topicsPattern, topicToSchemaType or inputSpecs");
        }
        for (String topic : allInputs) {
            if (!TopicName.isValid(topic)) {
                throw new IllegalArgumentException(String.format("Input topic %s is invalid", topic));
            }
        }
        if (!isEmpty(sinkConfig.getLogTopic())) {
            if (!TopicName.isValid(sinkConfig.getLogTopic())) {
                throw new IllegalArgumentException(
                        String.format("LogTopic topic %s is invalid", sinkConfig.getLogTopic()));
            }
        }

        if (sinkConfig.getParallelism() != null && sinkConfig.getParallelism() <= 0) {
            throw new IllegalArgumentException("Sink parallelism must be a positive number");
        }

        if (sinkConfig.getResources() != null) {
            ResourceConfigUtils.validate(sinkConfig.getResources());
        }

        if (sinkConfig.getTimeoutMs() != null && sinkConfig.getTimeoutMs() < 0) {
            throw new IllegalArgumentException("Sink timeout must be a positive number");
        }

        String sinkClassName = sinkConfig.getClassName();
        // if class name in sink config is not set, this should be a built-in sink
        // thus we should try to find it class name in the NAR service definition
        if (sinkClassName == null) {
            ConnectorDefinition connectorDefinition = sinkFunction.getFunctionMetaData(ConnectorDefinition.class);
            if (connectorDefinition == null) {
                throw new IllegalArgumentException(
                        "Sink package doesn't contain the META-INF/services/pulsar-io.yaml file.");

View on GitHub (pinned to 820761864e)

Solutions

  1. Set parallelism to at least 1, e.g. sinkConfig.setParallelism(1).
  2. Fix the code computing parallelism to clamp: Math.max(1, computed).
  3. Leave parallelism unset (null) to let defaults apply.
  4. Verify your YAML doesn't have 'parallelism: 0'.

Example fix

// before
sinkConfig.setParallelism(0);
// after
sinkConfig.setParallelism(1);
Defensive patterns

Strategy: validation

Validate before calling

if (sinkConfig.getParallelism() != null && sinkConfig.getParallelism() <= 0) {
    throw new IllegalArgumentException("parallelism must be >= 1");
}

Type guard

static boolean hasValidParallelism(SinkConfig cfg) {
    return cfg.getParallelism() == null || cfg.getParallelism() > 0;
}

Try / catch

try {
    SinkConfigUtils.validateAndExtractDetails(cfg, sinkPkg, transformPkg, true);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("parallelism")) {
        log.error("Sink parallelism must be positive: {}", cfg.getParallelism(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: SinkConfig.setParallelism(0) or negative, e.g. a computed parallelism that evaluated to 0, or YAML 'parallelism: 0'.

Common situations: Dynamic parallelism computed from partition count of 0-partitioned/empty clusters; default-value bugs where an int field initializes to 0 instead of null; user setting 0 thinking it means 'auto'.

Understand the failure class

Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.

Related errors


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