{"record":{"id":"f474700fa725eaf2","repo":"apache/pulsar","slug":"update-request-ignored-because-it-is-out-of-date","errorCode":null,"errorMessage":"Update request ignored because it is out of date. Please try again.","messagePattern":"Update request ignored because it is out of date\\. Please try again\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionMetaDataManager.java","lineNumber":267,"sourceCode":"        if (needsScheduling) {\n            this.schedulerManager.schedule();\n        }\n    }\n\n    private void checkRequestOutDated(FunctionMetaData functionMetaData, boolean delete) {\n        FunctionDetails details = functionMetaData.getFunctionDetails();\n        if (isRequestOutdated(details.getTenant(), details.getNamespace(),\n                details.getName(), functionMetaData.getVersion())) {\n            log.debug().attr(\"tenant\", details.getTenant())\n                    .attr(\"namespace\", details.getNamespace())\n                    .attr(\"functionName\", details.getName())\n                    .attr(\"version\", functionMetaData.getVersion())\n                    .log(\"Ignoring outdated request version\");\n            if (delete) {\n                throw new IllegalArgumentException(\n                        \"Delete request ignored because it is out of date. Please try again.\");\n            }\n            throw new IllegalArgumentException(\"Update request ignored because it is out of date. Please try again.\");\n        }\n    }\n\n    /**\n     * Acquires a exclusive producer.  This method cannot return null.  It can only return a valid exclusive producer\n     * or throw NotLeaderAnymore exception.\n     * @param isLeader if the worker is still the leader\n     * @return A valid exclusive producer\n     * @throws WorkerUtils.NotLeaderAnymore if the worker is no longer the leader.\n     */\n    public Producer<byte[]> acquireExclusiveWrite(Supplier<Boolean> isLeader) throws WorkerUtils.NotLeaderAnymore {\n        // creates exclusive producer for metadata topic\n        return WorkerUtils.createExclusiveProducerWithRetry(\n                pulsarClient,\n                workerConfig.getFunctionMetadataTopic(),\n                workerConfig.getWorkerId() + \"-leader\",\n                isLeader, 1000);\n    }","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionMetaDataManager.java#L249-L285","documentation":"checkRequestOutDated compares an incoming update request's metadata version against the locally cached version. If the request version is not newer (isRequestOutdated), the manager throws IllegalArgumentException(\"Update request ignored because it is out of date. Please try again.\") to reject stale writes to the function metadata topic.","triggerScenarios":"Calling updateFunctionOnLeader(..., delete=false) (via updateFunction / updateFunctionOnWorkerLeader) with a FunctionMetaData whose version <= the version currently cached on the leader worker — e.g. two clients updating the same function concurrently and the second one based its change on an older snapshot.","commonSituations":"Lost-update conflicts between multiple admins editing the same function; a client retrying after a partial failure with the original metadata object; a client whose read came from a non-leader worker that lagged behind.","solutions":["Fetch the latest function metadata, apply your change on top of it (version + 1), and resubmit the update.","Implement read-modify-write retry: on this error, GET current config, re-apply your modification, retry once or twice.","Check whether another process/admin is concurrently updating the same function and coordinate.","Don't cache FunctionMetaData across long intervals; always refresh immediately before update."],"exampleFix":"// before\nFunctionMetaData update = myOldSnapshot.toBuilder().setParallelism(4).build();\nworker.updateFunction(update, null);\n// after\nFunctionMetaData latest = getFunction(tenant, namespace, functionName);\nFunctionMetaData update = latest.toBuilder()\n        .setVersion(latest.getVersion() + 1)\n        .setParallelism(4).build();\nworker.updateFunction(update, null);","handlingStrategy":"retry","validationCode":"FunctionMetaData latest = admin.functions().getFunctionMetaData(tenant, ns, fn);\nif (update.getVersion() <= latest.getVersion()) {\n    // refresh version before submitting\n    update = update.toBuilder().setVersion(latest.getVersion() + 1).build();\n}","typeGuard":null,"tryCatchPattern":"try {\n    worker.updateFunction(update, uploadUrl);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Update request ignored\")) {\n        FunctionMetaData latest = refetch(tenant, ns, fn);\n        update = update.toBuilder().setVersion(latest.getVersion() + 1).build();\n        worker.updateFunction(update, uploadUrl);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always read-modify-write: GET current metadata, apply change, bump version, submit.","Add bounded retry (2-3 attempts) around function updates for concurrent-edit conflicts.","Avoid multiple automated processes updating the same function concurrently."],"tags":["pulsar-functions","version-conflict","optimistic-concurrency"],"backgroundTag":"stale-request-version","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}