apache/pulsar · error · IllegalArgumentException

Sink namespace cannot be null

Error message

Sink namespace cannot be null

What it means

validateAndExtractDetails throws IllegalArgumentException when the SinkConfig namespace field is null or empty. Tenant, namespace, and name together form the unique sink identity, so namespace must be present.

Source

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

            sinkConfig.setTransformFunctionClassName(functionDetails.getClassName());
        }
        if (!isEmpty(functionDetails.getUserConfig())) {
            sinkConfig.setTransformFunctionConfig(functionDetails.getUserConfig());
        }


        return sinkConfig;
    }

    public static ExtractedSinkDetails validateAndExtractDetails(SinkConfig sinkConfig,
                                                                 ValidatableFunctionPackage sinkFunction,
                                                                 ValidatableFunctionPackage transformFunction,
                                                                 boolean validateConnectorConfig) {
        if (isEmpty(sinkConfig.getTenant())) {
            throw new IllegalArgumentException("Sink tenant cannot be null");
        }
        if (isEmpty(sinkConfig.getNamespace())) {
            throw new IllegalArgumentException("Sink namespace cannot be null");
        }
        if (isEmpty(sinkConfig.getName())) {
            throw new IllegalArgumentException("Sink name cannot be null");
        }

        // make we sure we have one source of input
        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())) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Call sinkConfig.setNamespace("default") before submission.
  2. Add the 'namespace' key to your sink YAML/JSON config.
  3. If deriving from FunctionConfig, ensure namespace is copied over.
  4. Validate tenant/namespace/name triple client-side before calling the admin API.

Example fix

// before
sinkConfig.setTenant("public");
// after
sinkConfig.setTenant("public");
sinkConfig.setNamespace("default");
Defensive patterns

Strategy: validation

Validate before calling

if (sinkConfig.getNamespace() == null || sinkConfig.getNamespace().isEmpty()) {
    throw new IllegalArgumentException("sinkConfig.namespace must be set before submission");
}

Type guard

static boolean hasNamespace(SinkConfig cfg) {
    return cfg != null && cfg.getNamespace() != null && !cfg.getNamespace().trim().isEmpty();
}

Try / catch

try {
    SinkConfigUtils.validateAndExtractDetails(cfg, sinkPkg, transformPkg, true);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("namespace")) {
        log.error("Sink config missing namespace: fix config and retry", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Submitting a SinkConfig with tenant set but getNamespace() empty — e.g. sink created via admin API or SinkConfigUtils without setNamespace().

Common situations: Copy-pasted config templates missing 'namespace'; tenant-scoped tools that set tenant but forget namespace; migrations from older configs.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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