apache/pulsar · error · RestException
${e.getMessage()}
Error message
${e.getMessage()} What it means
Thrown by SourcesImpl.updateSource when SourceConfigUtils.validateUpdate rejects the merge of the submitted SourceConfig with the existing one. validateUpdate enforces immutability rules (tenant/namespace/name/class cannot change) and validates the new config; any exception it throws is re-wrapped as a 400 BAD_REQUEST RestException carrying the underlying validation message.
Source
Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java:316
if (!InstanceUtils.calculateSubjectType(existingComponent.getFunctionDetails()).equals(componentType)) {
log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", sourceName)
.attr("componentType", ComponentTypeUtils.toString(componentType)).log("/ / is not a");
throw new RestException(Response.Status.NOT_FOUND,
String.format("%s %s doesn't exist", ComponentTypeUtils.toString(componentType), sourceName));
}
SourceConfig existingSourceConfig =
SourceConfigUtils.convertFromDetails(existingComponent.getFunctionDetails());
// The rest end points take precedence over whatever is there in functionconfig
sourceConfig.setTenant(tenant);
sourceConfig.setNamespace(namespace);
sourceConfig.setName(sourceName);
SourceConfig mergedConfig;
try {
mergedConfig = SourceConfigUtils.validateUpdate(existingSourceConfig, sourceConfig);
} catch (Exception e) {
throw new RestException(Response.Status.BAD_REQUEST, e.getMessage());
}
if (existingSourceConfig.equals(mergedConfig) && isBlank(sourcePkgUrl) && uploadedInputStream == null
&& (updateOptions == null || !updateOptions.isUpdateAuthData())) {
log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", sourceName)
.log("/ / Update contains no changes");
throw new RestException(Response.Status.BAD_REQUEST, "Update contains no change");
}
FunctionDetails functionDetails;
File componentPackageFile = null;
try {
// validate parameters
try {
componentPackageFile = getPackageFile(
componentType,View on GitHub (pinned to 820761864e)
Solutions
- Fix the field named in e.getMessage() in the submitted SourceConfig (restore immutable fields tenant/namespace/name/className to their existing values)
- Fetch the current config first via GET and change only allowed fields, letting validateUpdate merge them
- Validate the config locally with SourceConfigUtils.validateUpdate(existingConfig, newConfig) before calling the update API
- If the message indicates serialization problems, ensure the payload is valid SourceConfig JSON with correct types
Example fix
// before: update payload changes className
SourceConfig cfg = getSourceConfig(existing);
cfg.setClassName("org.example.NewSource"); // rejected
// after: keep className, update only mutable fields
cfg.setClassName(existing.getClassName());
cfg.setProcessingGuarantees(ProcessingGuarantees.EFFECTIVELY_ONCE); Defensive patterns
Strategy: validation
Validate before calling
SourceConfig existing = admin.sources().getSourceConfig(tenant, ns, name);
try {
SourceConfigUtils.validateUpdate(existing, proposed);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid source update: " + e.getMessage(), e);
}
admin.sources().updateSource(tenant, ns, name, proposed); Try / catch
try {
admin.sources().updateSource(tenant, ns, name, cfg);
} catch (PulsarAdminException e) {
if (e.getStatusCode() == 400) {
log.error("Source update rejected: {}", e.getMessage());
} else { throw e; }
} Prevention
- GET the existing config and modify only mutable fields before PUT
- Never send tenant/namespace/name/className changes in an update payload
- Dry-run validateUpdate or SourceConfigUtils.validate locally before calling the API
When it happens
Trigger: Calling PUT /admin/v3/sources/{tenant}/{namespace}/{sourceName} (or WorkerUtils-issued updateSource) with a SourceConfig that fails SourceConfigUtils.validateUpdate: changing an immutable field (tenant, namespace, name, className), supplying an invalid/missing typeName, or a config that does not deserialize/validate.
Common situations: Renaming a connector's className in the update payload; sending a config serialized with a mismatched schema or bad JSON; submitting an update that accidentally alters the source's identity fields; upgrading connector config where a previously optional field is now validated strictly.
Understand the failure class
Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.
Related errors
- <validation message from IllegalArgumentException>
- %s Package is not provided
- %s %s doesn't have instance with id %s
- Function in trigger function has more than 1 input topics
- Function in trigger function has unidentified topic
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/b281656cd42e5e22.
Report an issue: GitHub.