apache/pulsar · warning · RestException
Path key doesn't match key in json
Error message
Path key doesn't match key in json
What it means
putFunctionState requires that the state key in the URL path exactly equals the "key" field of the JSON body. On mismatch the worker throws a 400 RestException "Path key doesn't match key in json". This prevents writing state under a different key than the request advertises.
Source
Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/ComponentImpl.java:1331
final FunctionState state,
final AuthenticationParameters authParams) {
if (!isWorkerServiceAvailable()) {
throwUnavailableException();
}
if (null == worker().getStateStoreProvider()) {
throwStateStoreUnvailableResponse();
}
throwRestExceptionIfUnauthorizedForNamespace(tenant, namespace, functionName, "put state for",
authParams);
if (!key.equals(state.getKey())) {
log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)
.log("/ / Bad putFunction Request, path key doesn't match key in json");
throw new RestException(Status.BAD_REQUEST, "Path key doesn't match key in json");
}
// validate parameters
try {
validateFunctionStateParams(tenant, namespace, functionName, key);
} catch (IllegalArgumentException e) {
log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)
.attr("key", key).exception(e).log("Invalid putFunctionState request @ / / / /");
throw new RestException(Status.BAD_REQUEST, e.getMessage());
}
FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();
if (!functionMetaDataManager.containsFunction(tenant, namespace, functionName)) {
log.warn().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", functionName)
.log("putFunctionState does not exist @ / / /");
throw new RestException(Status.NOT_FOUND, String.format("'%s' is not found", functionName));View on GitHub (pinned to 820761864e)
Solutions
- Make the JSON body's "key" field identical to the {key} path segment.
- If using a client/helper, build both URL and body from the same key variable.
- Log the request body before sending to confirm the key field value.
Example fix
// before
curl -X PUT .../state/counter -d '{"key":"count","stringValue":"1"}'
// after
curl -X PUT .../state/counter -d '{"key":"counter","stringValue":"1"}' Defensive patterns
Strategy: validation
Validate before calling
// Ensure body key matches path key before sending
function putStateRequest(pathKey, state) {
if (state.key !== pathKey) {
throw new Error(`Body key '${state.key}' must equal path key '${pathKey}'`);
}
return doPut(pathKey, state);
} Type guard
function keysMatch(pathKey, state) { return state != null && typeof state.key === 'string' && state.key === pathKey; } Try / catch
try {
await putState(tenant, ns, fn, key, body);
} catch (e) {
if (e.status === 400 && e.message.includes("Path key doesn't match")) {
// rebuild request with body.key = key and retry once
} else throw e;
} Prevention
- Derive both the URL path and the JSON body key from one variable.
- Add a client-side assertion that body.key === pathKey before every put.
- Avoid hand-editing example payloads in only one of the two places.
When it happens
Trigger: PUT .../functions/{tenant}/{namespace}/{functionName}/state/{pathKey} with a FunctionState JSON body whose "key" field differs from {pathKey}, e.g. path says 'counter' but body contains "key":"counters".
Common situations: Hand-built curl payloads where the body key was edited but the URL was not; clients that derive the path from one variable and the body from another; copy-paste of example payloads without updating both places.
Related errors
- <validation message from IllegalArgumentException>
- Invalid state value
- Tenant is not provided
- Namespace is not provided
- Sink name is not provided
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/623e23b53c8e13e7.
Report an issue: GitHub.