{"record":{"id":"0f3a9dabbaf9cce9","repo":"alibaba/nacos","slug":"over-threshold","errorCode":"OVER_THRESHOLD","errorMessage":"Legacy A2A Endpoint batch exceeds ${MAX_RUNTIME_ENDPOINTS} endpoints","messagePattern":"Legacy A2A Endpoint batch exceeds (.+?) endpoints","errorType":"exception","errorClass":"NacosException","httpStatus":503,"severity":"error","filePath":"ai/src/main/java/com/alibaba/nacos/ai/service/a2a/CanonicalA2aEndpointOperationService.java","lineNumber":100,"sourceCode":"        this.clientOperationService = clientOperationService;\n    }\n    \n    /**\n     * Replace one legacy exact-Version Endpoint publication in the canonical Runtime service.\n     *\n     * @param parentClientId original AI gRPC connection id\n     * @param namespaceId namespace identifier\n     * @param agentName Agent name\n     * @param endpoints complete legacy batch for one exact Version\n     * @throws NacosException when validation or Naming registration fails\n     */\n    public void register(String parentClientId, String namespaceId, String agentName,\n        Collection<AgentEndpoint> endpoints) throws NacosException {\n        if (endpoints == null || endpoints.isEmpty()) {\n            throw invalidEndpoint(\"Legacy A2A Endpoint batch must not be empty\");\n        }\n        if (endpoints.size() > MAX_RUNTIME_ENDPOINTS) {\n            throw new NacosException(NacosException.OVER_THRESHOLD,\n                \"Legacy A2A Endpoint batch exceeds \" + MAX_RUNTIME_ENDPOINTS + \" endpoints\");\n        }\n        AgentEndpoint firstEndpoint = endpoints.iterator().next();\n        if (firstEndpoint == null || StringUtils.isBlank(firstEndpoint.getVersion())) {\n            throw invalidEndpoint(\"Legacy A2A Endpoint Version must not be empty\");\n        }\n        String version = firstEndpoint.getVersion();\n        ArrayList<Instance> instances = new ArrayList<Instance>(endpoints.size());\n        for (AgentEndpoint endpoint : endpoints) {\n            if (endpoint == null || !version.equals(endpoint.getVersion())) {\n                throw invalidEndpoint(\n                    \"Legacy A2A Endpoint batch must contain one exact Version\");\n            }\n            try {\n                instances.add(toInstance(endpoint));\n            } catch (IllegalArgumentException e) {\n                throw invalidEndpoint(e.getMessage());\n            }","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/ai/src/main/java/com/alibaba/nacos/ai/service/a2a/CanonicalA2aEndpointOperationService.java#L82-L118","documentation":"Thrown by CanonicalA2aEndpointOperationService.register when the endpoint batch size exceeds MAX_RUNTIME_ENDPOINTS (1000). This protects the Naming subsystem from unreasonably large batch registrations in a single request. Each endpoint in the batch becomes a Naming instance registered under a child client, so capping the batch prevents resource exhaustion.","triggerScenarios":"Calling register with a Collection<AgentEndpoint> larger than 1000 entries for a single agent version. Bulk-importing endpoint lists without chunking. Auto-scaling event that reports a very large fleet in one batch.","commonSituations":"Large-scale deployment with many replicas reported in a single A2A endpoint registration. Misconfigured agent client that accumulates endpoints instead of reporting the current set. Migration script that dumps all historical endpoints at once.","solutions":["Chunk the endpoint batch into subsets of <= 1000 entries and call register for each chunk.","Reduce the batch to only currently-live endpoints — remove stale/dead entries before registering.","If 1000+ live endpoints is legitimate, discuss raising MAX_RUNTIME_ENDPOINTS with maintainers, but first verify the batch is not over-reported."],"exampleFix":"// before\nendpointOpService.register(parentClientId, ns, agentName, allEndpoints); // >1000\n\n// after\nint chunkSize = 1000;\nList<List<AgentEndpoint>> chunks = Lists.partition(new ArrayList<>(allEndpoints), chunkSize);\nfor (List<AgentEndpoint> chunk : chunks) {\n    endpointOpService.register(parentClientId, ns, agentName, chunk);\n}","handlingStrategy":"validation","validationCode":"// Chunk the batch before registering\nint MAX = 1000;\nList<AgentEndpoint> batch = new ArrayList<>(endpoints);\nif (batch.size() <= MAX) {\n    endpointOpService.register(parentClientId, ns, agentName, batch);\n} else {\n    for (int i = 0; i < batch.size(); i += MAX) {\n        List<AgentEndpoint> chunk = batch.subList(i, Math.min(i + MAX, batch.size()));\n        endpointOpService.register(parentClientId, ns, agentName, chunk);\n    }\n}","typeGuard":"public static boolean isWithinBatchLimit(Collection<AgentEndpoint> endpoints) {\n    return endpoints != null && endpoints.size() <= 1000;\n}","tryCatchPattern":"try {\n    endpointOpService.register(parentClientId, ns, agentName, endpoints);\n} catch (NacosException e) {\n    if (e.getCode() == NacosException.OVER_THRESHOLD) {\n        // re-chunk and retry\n        for (List<AgentEndpoint> chunk : partition(endpoints, 1000)) {\n            endpointOpService.register(parentClientId, ns, agentName, chunk);\n        }\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always chunk endpoint batches to <= 1000 entries.","Filter out dead/stale endpoints before registering to reduce batch size.","Monitor batch sizes in auto-scaling scenarios."],"tags":["a2a","endpoint","batch-limit","over-threshold","naming","capacity"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}