apache/pulsar · error · RestException
e.getMessage()
Error message
e.getMessage()
What it means
During updateFunction, FunctionConfigUtils.validateUpdate merges and validates the submitted FunctionConfig against the existing one. Any validation exception is converted to HTTP 400 with the raw e.getMessage() text. Common causes include illegal field changes (e.g. changing inputs/className/topics in disallowed ways), invalid values, or version-drift between the submitted config and the stored one.
Source
Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/FunctionsImpl.java:317
if (!InstanceUtils.calculateSubjectType(existingComponent.getFunctionDetails()).equals(componentType)) {
log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)
.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), functionName));
}
FunctionConfig existingFunctionConfig = FunctionConfigUtils
.convertFromDetails(existingComponent.getFunctionDetails());
// The rest end points take precedence over whatever is there in function config
functionConfig.setTenant(tenant);
functionConfig.setNamespace(namespace);
functionConfig.setName(functionName);
FunctionConfig mergedConfig;
try {
mergedConfig = FunctionConfigUtils.validateUpdate(existingFunctionConfig, functionConfig);
} catch (Exception e) {
throw new RestException(Response.Status.BAD_REQUEST, e.getMessage());
}
if (existingFunctionConfig.equals(mergedConfig) && isBlank(functionPkgUrl) && uploadedInputStream == null
&& (updateOptions == null || !updateOptions.isUpdateAuthData())) {
log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)
.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
- Read the 400 message text — it is the validator's explanation of which field is invalid.
- Only mutate allowed fields: GET current config, change settings, PUT the full merged config.
- For immutable changes (className, inputs), delete and re-create the function.
- Align client and cluster Pulsar versions so config field compatibility matches.
- Validate the config offline with FunctionConfigUtilsUpdated/the same validation before submitting.
Example fix
// before
FunctionConfig cfg = admin.functions().getFunctionConfig(t, ns, fn);
cfg.setClassName("com.newpkg.NewClass"); // immutable -> validateUpdate throws
admin.functions().updateFunction(t, ns, fn, cfg, null);
// after
admin.functions().deleteFunction(t, ns, fn);
admin.functions().createFunction(newCfgWithNewClassName(), null); Defensive patterns
Strategy: validation
Validate before calling
FunctionConfig current = admin.functions().getFunctionConfig(t, ns, fn);
FunctionConfig merged = mergeAndSanitize(current, submittedChanges); // only copy allowed mutable fields
try {
FunctionConfigUtils.validateUpdate(current, merged); // same validation the worker runs
} catch (Exception e) {
throw new IllegalArgumentException("Config will be rejected: " + e.getMessage(), e);
} Try / catch
try {
admin.functions().updateFunction(t, ns, fn, cfg, null);
} catch (PulsarAdminException e) {
if (e.getStatusCode() == 400) {
log.error("Update validation failed: {}", e.getMessage()); // raw validator reason
throw new ConfigValidationException(e.getMessage(), e);
}
throw e;
} Prevention
- Treat className/inputs/runtime as immutable; delete + recreate instead of updating.
- Run the same FunctionConfigUtils validation client-side before submitting.
- Keep client and cluster Pulsar versions aligned.
- Fetch the live config and apply minimal diffs rather than rebuilding configs from scratch.
When it happens
Trigger: PUT update where the merged config violates FunctionConfig rules — changing the class name or input topics on an existing function, incompatible runtime changes, invalid parallelism/resources, or a config produced by a newer client containing fields the worker's validator rejects.
Common situations: Editing function configs via scripts that mutate the GET result incompatibly; Pulsar version mismatch where newer client config fields fail older worker validation; attempting to change immutable fields instead of delete + recreate.
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
- %s %s cannot be admitted:- %s
- %s %s doesn't exist
- Update contains no change
- {e.getMessage()}
- cluster data is required
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/0111a0ea98258461.
Report an issue: GitHub.