{"record":{"id":"df1367bbfc2e3b5f","repo":"apache/dolphinscheduler","slug":"etcd-release-lock-error-lockkey","errorCode":null,"errorMessage":"etcd release lock error, lockKey: ","messagePattern":"etcd release lock error, lockKey: ","errorType":"exception","errorClass":"RegistryException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-etcd/src/main/java/org/apache/dolphinscheduler/plugin/registry/etcd/EtcdRegistry.java","lineNumber":404,"sourceCode":"            }\n            LockEntry lockEntry = lockEntryMap.get(key);\n            if (lockEntry == null) {\n                return true;\n            }\n            int newLockCount = lockEntry.lockCount.decrementAndGet();\n            if (newLockCount > 0) {\n                return true;\n            }\n            if (newLockCount < 0) {\n                throw new IllegalMonitorStateException(\"Etcd lock count has gone negative for lock: \" + key);\n            }\n            client.getLeaseClient().revoke(lockEntry.leaseId);\n            lockEntryMap.remove(key);\n            if (lockEntryMap.isEmpty()) {\n                threadLocalLockMap.remove();\n            }\n        } catch (Exception e) {\n            throw new RegistryException(\"etcd release lock error, lockKey: \" + key, e);\n        }\n        return true;\n    }\n\n    @Override\n    public void close() throws IOException {\n        // When the client closes, the watch also closes.\n        client.close();\n    }\n\n    private static ByteSequence byteSequence(String val) {\n        return ByteSequence.from(val, StandardCharsets.UTF_8);\n    }\n\n    private Event toEvent(final WatchEvent watchEvent, final String watchedPath) {\n        Event.Type eventType = null;\n        switch (watchEvent.getEventType()) {\n            case PUT:","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-etcd/src/main/java/org/apache/dolphinscheduler/plugin/registry/etcd/EtcdRegistry.java#L386-L422","documentation":"Wrapper thrown in EtcdRegistry.releaseLock: any failure while releasing the etcd lock — the lease revoke RPC failing, connection errors, or the nested IllegalMonitorStateException from the negative-count guard — is caught and rethrown as a RegistryException keyed by the lockKey, so callers see one uniform error with the original cause attached.","triggerScenarios":"Thrown at dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-etcd/src/main/java/org/apache/dolphinscheduler/plugin/registry/etcd/EtcdRegistry.java:404 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the cause chain to distinguish lease-revoke RPC failure from lock-count misuse","Check etcd connectivity and endpoint health if the cause is a gRPC/transport error","Ensure balanced acquire/release per thread (negative lock count is guarded separately)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}