apache/pulsar · error · IllegalArgumentException
Source tenant cannot be null
Error message
Source tenant cannot be null
What it means
SourceConfigUtils.validateAndExtractDetails validates a Pulsar IO Source configuration before creating/registering a source connector. The 'tenant' field is mandatory because every source must live inside a tenant/namespace/name fully-qualified function identity. The library throws IllegalArgumentException immediately when tenant is null or empty rather than producing a partially-constructed source.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java:266
sourceConfig.setResources(resources);
}
if (!isEmpty(functionDetails.getRuntimeFlags())) {
sourceConfig.setRuntimeFlags(functionDetails.getRuntimeFlags());
}
if (!isEmpty(functionDetails.getCustomRuntimeOptions())) {
sourceConfig.setCustomRuntimeOptions(functionDetails.getCustomRuntimeOptions());
}
return sourceConfig;
}
public static ExtractedSourceDetails validateAndExtractDetails(SourceConfig sourceConfig,
ValidatableFunctionPackage sourceFunction,
boolean validateConnectorConfig) {
if (isEmpty(sourceConfig.getTenant())) {
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");View on GitHub (pinned to 820761864e)
Solutions
- Set the tenant on the SourceConfig before validation, e.g. sourceConfig.setTenant("public") or the tenant you intend to use
- If the tenant should come from user input (CLI flag / REST field), check it is present and reject the request with a clear 400 message before calling validateAndExtractDetails
- If loading from a config file, add 'tenant' to the YAML/JSON and re-load the SourceConfig
Example fix
// before
SourceConfig cfg = new SourceConfig();
cfg.setNamespace("default");
cfg.setName("my-source");
// after
SourceConfig cfg = new SourceConfig();
cfg.setTenant("public");
cfg.setNamespace("default");
cfg.setName("my-source"); Defensive patterns
Strategy: validation
Validate before calling
if (sourceConfig == null || sourceConfig.getTenant() == null || sourceConfig.getTenant().isEmpty()) {
throw new IllegalArgumentException("sourceConfig.tenant must be set before validation");
} Type guard
static boolean hasTenant(SourceConfig cfg) {
return cfg != null && cfg.getTenant() != null && !cfg.getTenant().trim().isEmpty();
} Try / catch
try {
SourceConfigUtils.validateAndExtractDetails(cfg, pkg, true);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Source tenant cannot be null")) {
// surface a 400-style message asking the user to supply --tenant
}
} Prevention
- Always populate tenant/namespace/name together from a single builder or factory method
- Validate user-supplied config files at load time with your own schema check
- Default to the 'public' tenant only deliberately, never silently
When it happens
Trigger: Calling validateAndExtractDetails (directly or via source registration APIs like SourcesBase.create/update or the CLI 'pulsar-admin sources create') with a SourceConfig whose tenant field is null or an empty string.
Common situations: Building SourceConfig programmatically and forgetting setTenant(); deserializing a JSON/YAML source config file that lacks a 'tenant' key; copying a config template and deleting the tenant line; wiring configs through layers where tenant is filled in later than validation runs.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
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 namespace cannot be null
- Source name cannot be null
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/040bf08005083f76.
Report an issue: GitHub.