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
- Include a valid SourceConfig JSON body with the request and set Content-Type: application/json.
- Verify minimal required fields: className, topicName (or topicsPattern), and serialization configs.
- 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
- Always send the SourceConfig JSON body with Content-Type: application/json
- Validate config YAML/JSON with the CLI before submitting via REST
- Require className and topicName in your config templates
- Never pass the config as a query parameter
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
- cluster data is required
- %s %s cannot be admitted:- %s
- Tenant is not provided
- Namespace is not provided
- Source name is not provided
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/0469fbd1d227c065.
Report an issue: GitHub.