apache/pulsar · error · IllegalArgumentException

Source parallelism must be a positive number

Error message

Source parallelism must be a positive number

What it means

validateAndExtractDetails checks that SourceConfig.parallelism, when provided, is strictly greater than zero. Parallelism controls how many instances of the source run; zero or a negative value is nonsensical, so an IllegalArgumentException is thrown. A null parallelism is allowed (the framework applies its own default).

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java:284

            throw new IllegalArgumentException("Source tenant cannot be null");
        }
        if (isEmpty(sourceConfig.getNamespace())) {
            throw new IllegalArgumentException("Source namespace cannot be null");
        }
        if (isEmpty(sourceConfig.getName())) {
            throw new IllegalArgumentException("Source name cannot be null");
        }
        if (!isEmpty(sourceConfig.getTopicName()) && !TopicName.isValid(sourceConfig.getTopicName())) {
            throw new IllegalArgumentException("Topic name is invalid");
        }
        if (!isEmpty(sourceConfig.getLogTopic())) {
            if (!TopicName.isValid(sourceConfig.getLogTopic())) {
                throw new IllegalArgumentException(
                        String.format("LogTopic topic %s is invalid", sourceConfig.getLogTopic()));
            }
        }
        if (sourceConfig.getParallelism() != null && sourceConfig.getParallelism() <= 0) {
            throw new IllegalArgumentException("Source parallelism must be a positive number");
        }
        if (sourceConfig.getResources() != null) {
            ResourceConfigUtils.validate(sourceConfig.getResources());
        }

        String sourceClassName = sourceConfig.getClassName();
        // if class name in source config is not set, this should be a built-in source
        // thus we should try to find it class name in the NAR service definition
        if (sourceClassName == null) {
            ConnectorDefinition connectorDefinition = sourceFunction.getFunctionMetaData(ConnectorDefinition.class);
            if (connectorDefinition == null) {
                throw new IllegalArgumentException(
                        "Source package doesn't contain the META-INF/services/pulsar-io.yaml file.");
            }
            sourceClassName = connectorDefinition.getSourceClass();
            if (sourceClassName == null) {
                throw new IllegalArgumentException("Failed to extract source class from archive");
            }

View on GitHub (pinned to 820761864e)

Solutions

  1. Set parallelism to at least 1, e.g. sourceConfig.setParallelism(1)
  2. If parallelism is optional, leave it null instead of 0 so the framework default applies
  3. Guard numeric inputs before setting: only call setParallelism when the parsed value is > 0

Example fix

// before
int p = Integer.parseInt(System.getenv("PARALLELISM")); // 0 when unset
cfg.setParallelism(p);
// after
String pRaw = System.getenv("PARALLELISM");
if (pRaw != null && Integer.parseInt(pRaw) > 0) {
    cfg.setParallelism(Integer.parseInt(pRaw));
}
Defensive patterns

Strategy: validation

Validate before calling

if (cfg.getParallelism() != null && cfg.getParallelism() <= 0) {
    throw new IllegalArgumentException("parallelism must be > 0 (or null for the default)");
}

Type guard

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

Try / catch

try {
    SourceConfigUtils.validateAndExtractDetails(cfg, pkg, true);
} catch (IllegalArgumentException e) {
    if ("Source parallelism must be a positive number".equals(e.getMessage())) {
        // fall back to default parallelism or clamp the value to >= 1
    }
}

Prevention

When it happens

Trigger: Submitting a source with sourceConfig.setParallelism(0) or a negative value — often from a CLI flag '--parallelism 0', an env-driven integer defaulting to 0, or arithmetic producing a non-positive count.

Common situations: Users passing 0 thinking it means 'unlimited' or 'auto'; parsing an empty/unset env var into 0 and forwarding it; computing parallelism from cluster size when the size query returned 0.

Related errors


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