{"record":{"id":"86a03cdedb413a8b","repo":"apache/pulsar","slug":"not-the-leader","errorCode":null,"errorMessage":"Not the leader","messagePattern":"Not the leader","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionMetaDataManager.java","lineNumber":210,"sourceCode":"     * @return true if function exists and false if it does not\n     */\n    public synchronized boolean containsFunction(String tenant, String namespace, String functionName) {\n        return containsFunctionMetaData(tenant, namespace, functionName);\n    }\n\n    /**\n     * Called by the worker when we are in the leader mode.  In this state, we update our in-memory\n     * data structures and then write to the metadata topic.\n     * @param functionMetaData The function metadata in question\n     * @param delete Is this a delete operation\n     * @throws IllegalStateException if we are not the leader\n     * @throws IllegalArgumentException if the request is out of date.\n     */\n    public synchronized void updateFunctionOnLeader(FunctionMetaData functionMetaData, boolean delete)\n            throws IllegalStateException, IllegalArgumentException {\n        boolean needsScheduling;\n        if (exclusiveLeaderProducer == null) {\n            throw new IllegalStateException(\"Not the leader\");\n        }\n        // Check first to avoid local cache update failure\n        checkRequestOutDated(functionMetaData, delete);\n\n        byte[] toWrite;\n        if (workerConfig.getUseCompactedMetadataTopic()) {\n            if (delete) {\n                toWrite = \"\".getBytes();\n            } else {\n                toWrite = functionMetaData.toByteArray();\n            }\n        } else {\n            ServiceRequest serviceRequest = new ServiceRequest();\n            serviceRequest.setServiceRequestType(delete ? ServiceRequest.ServiceRequestType.DELETE\n                            : ServiceRequest.ServiceRequestType.UPDATE);\n            serviceRequest.setFunctionMetaData().copyFrom(functionMetaData);\n            serviceRequest.setWorkerId(workerConfig.getWorkerId());\n            serviceRequest.setRequestId(UUID.randomUUID().toString());","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionMetaDataManager.java#L192-L228","documentation":"FunctionMetaDataManager.updateFunctionOnLeader only accepts function metadata updates when this worker currently holds the exclusive leadership producer (exclusiveLeaderProducer != null). When the worker is not the leader (or has just lost leadership), it throws IllegalStateException(\"Not the leader\") so the caller can redirect the request to the current leader.","triggerScenarios":"Calling updateFunctionOnLeader (directly or via updateFunctionOnWorkerLeader / deregisterFunction) on a worker instance whose exclusiveLeaderProducer is null — i.e. the worker is not the functions worker leader, or leadership was just lost (failover) before this call.","commonSituations":"Client sent a register/update/delete function admin request to a non-leader worker; a leadership election happened concurrently and the old leader received a request after losing the exclusive producer; misconfigured worker with overlapping leaders during network partition.","solutions":["Retry the operation against the current leader worker (query worker clustering / leader broker via the functions worker admin API or let the HTTP redirect layer forward it).","Catch IllegalStateException and re-discover the leader before retrying rather than hammering the stale worker.","Check worker logs for recent leadership changes; ensure worker config (e.g. use state storage / HA settings) isn't causing frequent leader flapping.","Ensure only one worker is configured as eligible leader if you run a single-worker setup so leadership is stable."],"exampleFix":"// before\nworkerManager.updateFunctionOnWorkerLeader(tenant, namespace, functionName, functionMetaData, false);\n// after\ntry {\n    workerManager.updateFunctionOnWorkerLeader(tenant, namespace, functionName, functionMetaData, false);\n} catch (IllegalStateException e) {\n    if (\"Not the leader\".equals(e.getMessage())) {\n        URI leader = functions.getLeader();\n        // re-issue the request against the leader endpoint\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"URI leader = admin.functions().getLeader();\nif (!leader.equals(currentWorkerUri)) {\n    throw new IllegalStateException(\"Not the leader; redirect request to \" + leader);\n}","typeGuard":null,"tryCatchPattern":"try {\n    manager.updateFunctionOnLeader(meta, delete);\n} catch (IllegalStateException e) {\n    if (\"Not the leader\".equals(e.getMessage())) {\n        rediscoverLeaderAndRetry(meta, delete);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always route metadata updates to the current leader worker via the leader-discovery API.","Treat this error as a redirect signal, not a fatal failure.","Monitor leader flapping; unstable leadership multiplies this error."],"tags":["pulsar-functions","leader-election","state"],"backgroundTag":"not-the-leader","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"}