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
- Set parallelism to at least 1, e.g. sourceConfig.setParallelism(1)
- If parallelism is optional, leave it null instead of 0 so the framework default applies
- 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
- Leave parallelism null unless you have an explicit instance count
- Clamp env/CLI-derived integers: Math.max(1, parsedValue) when the field is present
- Never map 'unset' inputs to 0 — map them to null
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
- When effectively once processing guarantee is specified, ret
- Only one of retain ordering or retain key ordering can be se
- Receiver queue size should be >= zero
- Source tenant cannot be null
- Source namespace cannot be null
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/ee3287ac5142733f.
Report an issue: GitHub.