alibaba/nacos · error · NacosApiException

20004

20004

Error message

clientId [ {clientId} ] not exist

What it means

Thrown by ClientControllerV3.checkClientId when the requested client ID is not registered in the ClientManager. Returns HTTP 404 with ErrorCode.RESOURCE_NOT_FOUND=20004. This means the gRPC/HTTP connection-based client (identified by its clientId) is not known to this Nacos server node — it may have never connected, disconnected, or is managed by a different node.

Source

Thrown at naming/src/main/java/com/alibaba/nacos/naming/controllers/v3/ClientControllerV3.java:163

                clientServiceForm.getIp(),
                clientServiceForm.getPort()));
    }
    
    /**
     * Query the responsible server for a given client based on its IP and port.
     */
    @Since("3.0.0")
    @GetMapping("/distro")
    @Secured(resource = UtilsAndCommons.CLIENT_CONTROLLER_V3_ADMIN_PATH, action = ActionTypes.READ,
        apiType = ApiType.ADMIN_API)
    public Result<Map<String, Object>> getResponsibleServer4Client(@RequestParam String ip,
        @RequestParam String port) {
        return Result.success(clientServiceV2Impl.getResponsibleServer4Client(ip, port));
    }
    
    private void checkClientId(String clientId) throws NacosApiException {
        if (!clientManager.contains(clientId)) {
            throw new NacosApiException(HttpStatus.NOT_FOUND.value(), ErrorCode.RESOURCE_NOT_FOUND,
                "clientId [ " + clientId + " ] not exist");
        }
    }
}

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Verify the clientId is currently connected by listing clients first (getClientList) and confirming the ID exists.
  2. Route the query to the correct Nacos server node that owns the client connection (use the /distro endpoint to find the responsible server).
  3. Re-register the client if it was unintentionally disconnected.
  4. Check that the client is still alive and its heartbeat/connection is active.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the client exists before querying detail
List<String> clientIds = clientService.getClientList();
if (!clientIds.contains(targetClientId)) {
    // route to the responsible server via /distro or skip
    log.warn("clientId {} not on this node", targetClientId);
}

Try / catch

try {
    ClientSummaryInfo detail = clientService.getClientDetail(clientId);
} catch (NacosApiException e) {
    if (e.getErrCode() == NacosException.NOT_FOUND
            || ErrorCode.RESOURCE_NOT_FOUND.getCode() == e.getErrCode()) {
        // client disconnected or is on another node; refresh client list
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling an admin API endpoint on ClientControllerV3 that delegates to checkClientId (e.g. client detail, client publish info) with a clientId that clientManager.contains() returns false for. The clientId typically encodes ip:port or a connection-based identifier.

Common situations: Querying a client that has already disconnected (connection closed, client crashed). Querying a clientId that belongs to a different Nacos server node in the cluster (Distro ownership). Using a stale or fabricated clientId. The client connected to the cluster but this node does not hold its connection.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/9f3a56bccc74f2a1. Report an issue: GitHub.