{"record":{"id":"f2ec6f362185fef9","repo":"apache/dolphinscheduler","slug":"the-client-is-already-registered","errorCode":null,"errorMessage":"The client is already registered: ","messagePattern":"The client is already registered: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java","lineNumber":150,"sourceCode":"    @Override\n    public void registerClient(IJdbcRegistryClient jdbcRegistryClient) {\n        checkNotNull(jdbcRegistryClient);\n\n        JdbcRegistryClientIdentify jdbcRegistryClientIdentify = jdbcRegistryClient.getJdbcRegistryClientIdentify();\n        checkNotNull(jdbcRegistryClientIdentify);\n\n        JdbcRegistryClientHeartbeatDTO registryClientDTO = JdbcRegistryClientHeartbeatDTO.builder()\n                .id(jdbcRegistryClientIdentify.getClientId())\n                .clientName(jdbcRegistryClientIdentify.getClientName())\n                .clientConfig(\n                        new JdbcRegistryClientHeartbeatDTO.ClientConfig(\n                                jdbcRegistryProperties.getSessionTimeout().toMillis()))\n                .createTime(new Date())\n                .lastHeartbeatTime(System.currentTimeMillis())\n                .build();\n\n        if (jdbcRegistryClientDTOMap.containsKey(jdbcRegistryClientIdentify)) {\n            throw new IllegalArgumentException(\"The client is already registered: \" + jdbcRegistryClientIdentify);\n        }\n        jdbcRegistryClientRepository.insert(registryClientDTO);\n        jdbcRegistryClients.add(jdbcRegistryClient);\n        jdbcRegistryClientDTOMap.put(jdbcRegistryClientIdentify, registryClientDTO);\n    }\n\n    @Override\n    public void deregisterClient(IJdbcRegistryClient jdbcRegistryClient) {\n        checkNotNull(jdbcRegistryClient);\n        final JdbcRegistryClientIdentify clientIdentify = jdbcRegistryClient.getJdbcRegistryClientIdentify();\n        checkNotNull(clientIdentify);\n\n        jdbcRegistryClients.removeIf(client -> clientIdentify.equals(client.getJdbcRegistryClientIdentify()));\n        jdbcRegistryClientDTOMap.remove(jdbcRegistryClient.getJdbcRegistryClientIdentify());\n\n        doPurgeJdbcRegistryClientInDB(Lists.newArrayList(clientIdentify.getClientId()));\n    }\n","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java#L132-L168","documentation":"JdbcRegistryServer.registerClient rejects registering a client whose identity (host, port and other identity fields) already exists in the server's client map. Each connected registry client must have a unique identity so heartbeats, ephemeral data ownership, and lock ownership remain unambiguous. A duplicate registration throws IllegalArgumentException.","triggerScenarios":"Calling connect/register twice from the same process with identical identity parameters; two JVMs configured with the same host/port identity; server-side map retaining the client after an incomplete disconnect.","commonSituations":"Application restart logic that forgets to close the old registry client before reconnecting, cloned VMs/containers sharing identical configured identity values, retry loops that re-register without checking existing state.","solutions":["Close the existing registry client before reconnecting so the old registration is removed","Make client identity unique (add PID, random UUID, or timestamp to host/port identity)","Check whether the client is already connected and reuse the existing instance instead of re-registering"],"exampleFix":"// before\nregistryClient = new JdbcRegistryClient(identity); // identity reused after restart\nregistryClient.connect();\n// after\nif (registryClient != null) {\n    registryClient.close();\n}\nidentity = IdentityFactory.newUniqueIdentity();\nregistryClient = new JdbcRegistryClient(identity);\nregistryClient.connect();","handlingStrategy":"try-catch","validationCode":"if (existingClient != null && existingClient.isConnected()) { return existingClient; }","typeGuard":null,"tryCatchPattern":"try { server.registerClient(identity...); } catch (IllegalArgumentException e) { log.warn(\"Client already registered, reusing existing connection\"); }","preventionTips":["Close old clients before reconnecting on restart","Include a UUID/PID in client identity","Guard registration with a local connected flag"],"tags":["registry","duplicate-registration","client-lifecycle"],"backgroundTag":"file-already-exists","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}