apache/pulsar · error · RestException
e.getMessage()
Error message
e.getMessage()
What it means
HTTP 400 thrown by FunctionsImplV2.registerFunction when the submitted functionDetailsJson cannot be parsed into a FunctionDetails proto JSON. Any parse/validation exception (bad JSON syntax, missing required fields like className/inputs, invalid enum values) is caught and its message returned as the 400 body.
Source
Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/FunctionsImplV2.java:111
for (FunctionStatus.FunctionInstanceStatus instanceStatus : functionStatus.instances) {
toProto(functionStatusList.addFunctionStatus(),
instanceStatus.getStatus(),
String.valueOf(instanceStatus.getInstanceId()));
}
String jsonResponse = functionStatusList.toJson();
return Response.status(Response.Status.OK).entity(jsonResponse).build();
}
@Override
public Response registerFunction(String tenant, String namespace, String functionName, InputStream
uploadedInputStream, FormDataContentDisposition fileDetail, String functionPkgUrl, String
functionDetailsJson, AuthenticationParameters authParams) {
FunctionDetails functionDetails = new FunctionDetails();
try {
functionDetails.parseFromJson(functionDetailsJson);
} catch (Exception e) {
throw new RestException(Response.Status.BAD_REQUEST, e.getMessage());
}
FunctionConfig functionConfig = FunctionConfigUtils.convertFromDetails(functionDetails);
delegate.registerFunction(tenant, namespace, functionName, uploadedInputStream, fileDetail,
functionPkgUrl, functionConfig, authParams);
return Response.ok().build();
}
@Override
public Response updateFunction(String tenant, String namespace, String functionName,
InputStream uploadedInputStream, FormDataContentDisposition fileDetail,
String functionPkgUrl, String functionDetailsJson,
AuthenticationParameters authParams) {
FunctionDetails functionDetails = new FunctionDetails();
try {
functionDetails.parseFromJson(functionDetailsJson);
} catch (Exception e) {View on GitHub (pinned to 820761864e)
Solutions
- Validate the JSON against FunctionDetails proto format: required top-level fields and correct enum spellings (e.g. RuntimeType JAVA).
- Use FunctionDetails::toJson (or FunctionConfigUtils.convertToDetails on a FunctionConfig) client-side to generate the payload instead of hand-writing JSON.
- Read the 400 message body — protobuf JSON parse errors usually name the offending field or token.
Example fix
// before
String details = "{\"classname\": \"com.ex.Fn\"}"; // typo'd field
// after
FunctionDetails details = FunctionConfigUtils.convertToDetails(functionConfig);
registerFunction(tenant, ns, name, stream, fileDetail, pkgUrl, details.toJson(), authParams); Defensive patterns
Strategy: validation
Validate before calling
try {
FunctionDetails details = FunctionDetails.parseFromJson(functionDetailsJson); // dry-run parse client-side
} catch (Exception e) {
throw new IllegalArgumentException("invalid functionDetails JSON: " + e.getMessage());
} Type guard
function isJsonObject(s) {
try { return JSON.parse(s) !== null && typeof JSON.parse(s) === 'object'; } catch { return false; }
} Try / catch
try {
admin.registerFunctionV2(..., functionDetailsJson);
} catch (ApiException e) {
if (e.code() == 400) {
// log e.body(): names the JSON parse/validation failure
}
} Prevention
- Generate functionDetailsJson programmatically via FunctionDetails.toJson rather than hand-writing JSON.
- Keep required fields (className, inputs, output, runtime) present and enum values correctly spelled.
- Round-trip parse the JSON client-side before sending to catch schema drift after upgrades.
When it happens
Trigger: POSTing to the V2 functions registration endpoint with a functionDetails field that is not valid JSON, or JSON missing required FunctionDetails fields (tenant, namespace, name, className, inputs, output, runtime), or an unknown runtime/enum string.
Common situations: Hand-rolled JSON payloads with typo'd field names (e.g. 'classname' vs 'className'); passing the whole FunctionConfig JSON (source/sink shape) where FunctionDetails proto JSON is expected; double-encoding the JSON string; schema drift after upgrading Pulsar so previously-valid fields are rejected.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Corrupt Function MetaData
- No Function %s found
- Function package is not provided
- Cannot terminate non-persistent topic: ${segmentTopic}
- e.getMessage()
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/f14c860a1e44b4d6.
Report an issue: GitHub.