{"record":{"id":"eff4c2b46e8ece45","repo":"alibaba/nacos","slug":"401-eff4c2","errorCode":"-401","errorMessage":"Client [%s] connection already disconnect, can't register ephemeral instance.","messagePattern":"Client \\[(.+?)\\] connection already disconnect, can't register ephemeral instance\\.","errorType":"exception","errorClass":"NacosRuntimeException","httpStatus":null,"severity":"error","filePath":"naming/src/main/java/com/alibaba/nacos/naming/core/v2/service/impl/EphemeralClientOperationServiceImpl.java","lineNumber":156,"sourceCode":"            new ClientOperationEvent.ClientSubscribeServiceEvent(singleton, clientId));\n    }\n    \n    @Override\n    public void unsubscribeService(Service service, Subscriber subscriber, String clientId) {\n        Service singleton =\n            ServiceManager.getInstance().getSingletonIfExist(service).orElse(service);\n        Client client = clientManager.getClient(clientId);\n        checkClientIsLegal(client, clientId);\n        client.removeServiceSubscriber(singleton);\n        client.setLastUpdatedTime();\n        NotifyCenter.publishEvent(\n            new ClientOperationEvent.ClientUnsubscribeServiceEvent(singleton, clientId));\n    }\n    \n    private void checkClientIsLegal(Client client, String clientId) {\n        if (client == null) {\n            Loggers.SRV_LOG.warn(\"Client connection {} already disconnect\", clientId);\n            throw new NacosRuntimeException(NacosException.CLIENT_DISCONNECT,\n                String.format(\n                    \"Client [%s] connection already disconnect, can't register ephemeral instance.\",\n                    clientId));\n        }\n        if (!client.isEphemeral()) {\n            Loggers.SRV_LOG.warn(\"Client connection {} type is not ephemeral\", clientId);\n            throw new NacosRuntimeException(NacosException.INVALID_PARAM,\n                String.format(\n                    \"Current client [%s] is persistent client, can't register ephemeral instance.\",\n                    clientId));\n        }\n    }\n}\n","sourceCodeStart":138,"sourceCodeEnd":170,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/naming/src/main/java/com/alibaba/nacos/naming/core/v2/service/impl/EphemeralClientOperationServiceImpl.java#L138-L170","documentation":"Thrown by EphemeralClientOperationServiceImpl.checkClientIsLegal when the Client retrieved by clientId from clientManager is null — meaning the gRPC/HTTP connection for that clientId has been disconnected and the Client object was removed. Error code -401 (CLIENT_DISCONNECT) via NacosRuntimeException. The server cannot register an ephemeral instance against a connection that no longer exists.","triggerScenarios":"A register/deregister/subscriber operation arrives for a clientId whose underlying gRPC connection has been closed (client crashed, network drop, idle-timeout eviction). The ClientManager has already removed the Client, so getClient returns null.","commonSituations":"Client process crashed or was killed without graceful disconnect. gRPC connection idle timeout fired on the server side. Network partition between client and server. Server restarted and lost all in-memory client connections; clients retry before re-establishing the connection.","solutions":["Ensure the client SDK re-establishes the gRPC connection (and gets a new clientId) before retrying registration.","Check client-side connection health and reconnect logic (the SDK should auto-reconnect on CLIENT_DISCONNECT).","Increase server-side client idle timeout if connections are being evicted prematurely (nacos.remote.client.grpc.timeout).","If the error persists, restart the client application to force a clean reconnection."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"Client client = clientManager.getClient(clientId);\nif (client == null) {\n    // connection lost — client SDK must reconnect and obtain a new clientId\n    // before retrying registration\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    ephemeralClientOperationService.registerInstance(service, instance, clientId);\n} catch (NacosRuntimeException e) {\n    if (e.getErrCode() == NacosException.CLIENT_DISCONNECT) {\n        // -401: reconnect via SDK, then retry with the new clientId\n    } else throw e;\n}","preventionTips":["Ensure the client SDK auto-reconnects on CLIENT_DISCONNECT and retries registration.","Monitor gRPC connection health and idle-timeout settings.","Increase nacos.remote.client.grpc.timeout if connections are evicted prematurely."],"tags":["naming","client-disconnect","grpc","connection","ephemeral"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}