{"record":{"id":"1b987bdc7fd12add","repo":"alibaba/nacos","slug":"failed-to-acquire-lock","errorCode":null,"errorMessage":"Failed to acquire lock: {}","messagePattern":"Failed to acquire lock: (.+?)","errorType":"exception","errorClass":"NacosLockException","httpStatus":null,"severity":"error","filePath":"client/src/main/java/com/alibaba/nacos/client/lock/NacosLock.java","lineNumber":172,"sourceCode":"                    if (result.getReentrantCount() == 1) {\n                        watchdog.register(key, grpcClient, instance);\n                    }\n                    return;\n                }\n                firstAttempt = false;\n                grpcClient.waitForNotification(key, currentOwner(), NOTIFICATION_POLL_TIMEOUT_MS);\n            } catch (InterruptedException e) {\n                // Clear interrupt flag so gRPC cancel request doesn't throw,\n                // then restore it after the synchronous server-side cleanup.\n                grpcClient.cancelWait(key, lockType, currentOwner());\n                Thread.currentThread().interrupt();\n                localReentrantCount.remove();\n                throw new NacosLockException(\"Lock interrupted\", e);\n            } catch (NacosException e) {\n                LOGGER.error(\"Failed to acquire lock, key={}\", key, e);\n                grpcClient.cancelWait(key, lockType, currentOwner());\n                localReentrantCount.remove();\n                throw new NacosLockException(\"Failed to acquire lock: \" + key, e);\n            }\n        }\n    }\n    \n    @Override\n    public void lockInterruptibly() throws InterruptedException {\n        checkReentrantGuard();\n        boolean firstAttempt = true;\n        while (true) {\n            if (Thread.interrupted()) {\n                if (!firstAttempt) {\n                    grpcClient.cancelWait(key, lockType, currentOwner());\n                }\n                throw new InterruptedException();\n            }\n            try {\n                LockInstance instance = buildInstance(-1);\n                instance.setWaitTime(DEFAULT_SERVER_WAIT_TIME_MS);","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/client/src/main/java/com/alibaba/nacos/client/lock/NacosLock.java#L154-L190","documentation":"Thrown by NacosLock.lock() when a NacosException (not InterruptedException) occurs during the acquisition loop — typically a gRPC transport error, server-side rejection, or connection failure. The method logs the error, cancels the server-side wait, cleans up the ThreadLocal count, and wraps the original NacosException in a NacosLockException with the message \"Failed to acquire lock: <key>\".","triggerScenarios":"The gRPC client encounters a transport error (connection lost, server unreachable) during lockWithResult or waitForNotification; the server returns an error response that maps to a NacosException; the lock service is temporarily unavailable or the server is restarting.","commonSituations":"Network partition or gRPC channel reset between client and Nacos server; the Nacos server is down or restarting; the gRPC connection was idle-closed; authentication token expired mid-acquisition; the server is overloaded and rejects the request.","solutions":["Check the Nacos server health and gRPC connectivity (port 9849 for gRPC).","Examine the wrapped NacosException cause for the specific error code (e.g. connection refused, UNAVAILABLE).","Implement a retry-with-backoff strategy for transient transport errors.","Ensure the gRPC connection is established and authenticated before acquiring locks.","Verify the server version supports the distributed lock feature."],"exampleFix":"// before\nlock.lock(); // throws NacosLockException on gRPC failure\n\n// after — retry with backoff\nint attempts = 0;\nwhile (true) {\n    try {\n        lock.lock();\n        break;\n    } catch (NacosLockException e) {\n        if (++attempts > MAX_RETRIES) throw e;\n        Thread.sleep(backoffMillis(attempts));\n    }\n}","handlingStrategy":"retry","validationCode":"// Pre-check: verify gRPC connectivity before acquiring\nboolean isServerReachable(LockGrpcClient client) {\n    try {\n        return client.isAlive(); // or a lightweight health check\n    } catch (Exception e) {\n        return false;\n    }\n}","typeGuard":"// N/A — transport errors are runtime failures, not type-level.","tryCatchPattern":"int attempts = 0;\nwhile (true) {\n    try {\n        lock.lock();\n        break;\n    } catch (NacosLockException e) {\n        Throwable cause = e.getCause();\n        if (cause instanceof NacosException && isTransient((NacosException) cause)) {\n            if (++attempts > MAX_RETRIES) throw e;\n            Thread.sleep(backoffMillis(attempts));\n        } else {\n            throw e;\n        }\n    }\n}","preventionTips":["Verify Nacos server health and gRPC port (9849) before acquiring locks.","Implement retry-with-backoff for transient gRPC errors.","Monitor gRPC channel state and reconnect proactively.","Ensure authentication tokens are valid for the duration of lock holds."],"tags":["lock","distributed","grpc","network","connection"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}