apache/pulsar · warning · RestException

Source config is not provided

Error message

Source config is not provided

What it means

registerSource requires a SourceConfig body. If sourceConfig is null after the name checks, it returns HTTP 400 'Source config is not provided'. The config carries topicName, className, serialization class, etc., so it is mandatory.

Source

Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java:99

                               final String sourcePkgUrl,
                               final SourceConfig sourceConfig,
                               final AuthenticationParameters authParams) {

        if (!isWorkerServiceAvailable()) {
            throwUnavailableException();
        }

        if (tenant == null) {
            throw new RestException(Response.Status.BAD_REQUEST, "Tenant is not provided");
        }
        if (namespace == null) {
            throw new RestException(Response.Status.BAD_REQUEST, "Namespace is not provided");
        }
        if (sourceName == null) {
            throw new RestException(Response.Status.BAD_REQUEST, "Source name is not provided");
        }
        if (sourceConfig == null) {
            throw new RestException(Response.Status.BAD_REQUEST, "Source config is not provided");
        }

        throwRestExceptionIfUnauthorizedForNamespace(tenant, namespace, sourceName, "register", authParams);

        try {
            // Check tenant exists
            worker().getBrokerAdmin().tenants().getTenantInfo(tenant);

            String qualifiedNamespace = tenant + "/" + namespace;
            List<String> namespaces = worker().getBrokerAdmin().namespaces().getNamespaces(tenant);
            if (namespaces != null && !namespaces.contains(qualifiedNamespace)) {
                String qualifiedNamespaceWithCluster = String.format("%s/%s/%s", tenant,
                        worker().getWorkerConfig().getPulsarFunctionsCluster(), namespace);
                if (namespaces != null && !namespaces.contains(qualifiedNamespaceWithCluster)) {
                    log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", sourceName)

                            .attr("namespace3", namespace).log("/ / Namespace does not exist");
                    throw new RestException(Response.Status.BAD_REQUEST, "Namespace does not exist");

View on GitHub (pinned to 820761864e)

Solutions

  1. Include a valid SourceConfig JSON body with the request and set Content-Type: application/json.
  2. Verify minimal required fields: className, topicName (or topicsPattern), and serialization configs.
  3. In programmatic use, construct and pass a non-null SourceConfig instance.

Example fix

// before
curl -X POST .../sources/t/n/s   // no body -> 400
// after
curl -X POST -H 'Content-Type: application/json' -d @sourceConfig.yaml.json .../sources/t/n/s
Defensive patterns

Strategy: validation

Validate before calling

if (sourceConfig == null) throw new IllegalArgumentException("SourceConfig body is required");
// and for REST: always send Content-Type: application/json with a non-empty body

Type guard

boolean hasRequiredSourceConfig(SourceConfig c) { return c != null && c.getClassName() != null && c.getTopicName() != null; }

Try / catch

try { admin.sources().createSource(tenant, ns, name, file, cfg); } catch (PulsarAdminException e) { if (e.getStatusCode() == 400) { /* inspect message, fix body */ } throw e; }

Prevention

When it happens

Trigger: POST to the source endpoint without a JSON SourceConfig body, with a wrong Content-Type so the body failed to bind, or programmatic createSource calls passing null config.

Common situations: curl calls omitting -d/--data or the @file argument; sending the config as a query param instead of the request body; SDK wrapper dropping the config object; misconfigured Content-Type (text/plain instead of application/json).

Related errors


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