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

  1. Fix the field named in e.getMessage() in the submitted SourceConfig (restore immutable fields tenant/namespace/name/className to their existing values)
  2. Fetch the current config first via GET and change only allowed fields, letting validateUpdate merge them
  3. Validate the config locally with SourceConfigUtils.validateUpdate(existingConfig, newConfig) before calling the update API
  4. 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

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


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