{"record":{"id":"219a77e0a7267543","repo":"apache/pulsar","slug":"corrupt-function-metadata","errorCode":null,"errorMessage":"Corrupt Function MetaData","messagePattern":"Corrupt Function MetaData","errorType":"http","errorClass":"RestException","httpStatus":400,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/FunctionsImpl.java","lineNumber":727,"sourceCode":"            }\n        }\n\n        if (tenant == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Tenant is not provided\");\n        }\n        if (namespace == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Namespace is not provided\");\n        }\n        if (functionName == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Function name is not provided\");\n        }\n        FunctionMetaData functionMetaData;\n        try {\n            byte[] data = uploadedInputStream.readAllBytes();\n            functionMetaData = new FunctionMetaData();\n            functionMetaData.parseFrom(data);\n        } catch (IOException e) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Corrupt Function MetaData\");\n        }\n\n        // Redirect if we are not the leader\n        if (!worker().getLeaderService().isLeader()) {\n            WorkerInfo workerInfo = worker().getMembershipManager().getLeader();\n            if (workerInfo == null || workerInfo.getWorkerId().equals(worker().getWorkerConfig().getWorkerId())) {\n                throw new RestException(Response.Status.SERVICE_UNAVAILABLE,\n                        \"Leader not yet ready. Please retry again\");\n            }\n            URI redirect = UriBuilder.fromUri(uri).host(workerInfo.getWorkerHostname())\n                    .port(workerInfo.getPort()).build();\n            throw new WebApplicationException(Response.temporaryRedirect(redirect).build());\n        }\n\n        // Its possible that we are not the leader anymore. That will be taken care of by FunctionMetaDataManager\n        FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();\n        try {\n            functionMetaDataManager.updateFunctionOnLeader(functionMetaData, delete);","sourceCodeStart":709,"sourceCodeEnd":745,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/FunctionsImpl.java#L709-L745","documentation":"HTTP 400 thrown when the uploaded request body cannot be parsed as a FunctionMetaData protobuf (parseFrom throws IOException). The worker expects the updateOnLeader endpoint body to be a serialized FunctionMetaData proto; any bytes that are not a valid encoding of that message are rejected as corrupt metadata.","triggerScenarios":"POSTing to the updateOnLeader endpoint with a body that is JSON, form data, a truncated file, or otherwise not the exact protobuf binary encoding of FunctionMetaData; sending an empty body; a client serializing a different proto type into the stream.","commonSituations":"Sending JSON because the public functions API accepts JSON-based configs (version mismatch between API flavors); a proxy or client library re-encoding or chunk-truncating the binary body; uploading the wrong file (e.g. the function jar) as the metadata payload; charset/encoding mangling of the binary payload.","solutions":["Serialize the body as FunctionMetaData::writeTo protobuf bytes, not JSON or form data.","Verify the payload was not truncated: compare sent byte count with FunctionMetaData's serialized size.","Confirm the proto schema version on the client matches the server's FunctionMetaData definition (compatible wire format)."],"exampleFix":"// before\nString json = new Gson().toJson(metaData);\nrequest.body(json);\n// after\nbyte[] data = metaData.toByteArray();\nrequest.body(RequestBody.create(data, MediaType.parse(\"application/x-protobuf\")));","handlingStrategy":"try-catch","validationCode":"byte[] data = metaData.toByteArray();\nif (data.length == 0) throw new IllegalStateException(\"empty FunctionMetaData payload\");","typeGuard":null,"tryCatchPattern":"try {\n    // send protobuf body\n} catch (ApiException e) {\n    if (e.code() == 400 && e.body().contains(\"Corrupt Function MetaData\")) {\n        // re-serialize with FunctionMetaData::toByteArray and retry once\n    }\n}","preventionTips":["Always send FunctionMetaData.toByteArray() with an application/x-protobuf content type.","Never send JSON to the updateOnLeader endpoint; it is protobuf-only."],"tags":["rest","bad-request","protobuf","pulsar-functions"],"backgroundTag":"malformed-payload","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}