alibaba/nacos · error · NacosException

OVER_THRESHOLD

OVER_THRESHOLD

Error message

Legacy A2A Endpoint batch exceeds ${MAX_RUNTIME_ENDPOINTS} endpoints

What it means

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.

Source

Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/a2a/CanonicalA2aEndpointOperationService.java:100

        this.clientOperationService = clientOperationService;
    }
    
    /**
     * Replace one legacy exact-Version Endpoint publication in the canonical Runtime service.
     *
     * @param parentClientId original AI gRPC connection id
     * @param namespaceId namespace identifier
     * @param agentName Agent name
     * @param endpoints complete legacy batch for one exact Version
     * @throws NacosException when validation or Naming registration fails
     */
    public void register(String parentClientId, String namespaceId, String agentName,
        Collection<AgentEndpoint> endpoints) throws NacosException {
        if (endpoints == null || endpoints.isEmpty()) {
            throw invalidEndpoint("Legacy A2A Endpoint batch must not be empty");
        }
        if (endpoints.size() > MAX_RUNTIME_ENDPOINTS) {
            throw new NacosException(NacosException.OVER_THRESHOLD,
                "Legacy A2A Endpoint batch exceeds " + MAX_RUNTIME_ENDPOINTS + " endpoints");
        }
        AgentEndpoint firstEndpoint = endpoints.iterator().next();
        if (firstEndpoint == null || StringUtils.isBlank(firstEndpoint.getVersion())) {
            throw invalidEndpoint("Legacy A2A Endpoint Version must not be empty");
        }
        String version = firstEndpoint.getVersion();
        ArrayList<Instance> instances = new ArrayList<Instance>(endpoints.size());
        for (AgentEndpoint endpoint : endpoints) {
            if (endpoint == null || !version.equals(endpoint.getVersion())) {
                throw invalidEndpoint(
                    "Legacy A2A Endpoint batch must contain one exact Version");
            }
            try {
                instances.add(toInstance(endpoint));
            } catch (IllegalArgumentException e) {
                throw invalidEndpoint(e.getMessage());
            }

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Chunk the endpoint batch into subsets of <= 1000 entries and call register for each chunk.
  2. Reduce the batch to only currently-live endpoints — remove stale/dead entries before registering.
  3. If 1000+ live endpoints is legitimate, discuss raising MAX_RUNTIME_ENDPOINTS with maintainers, but first verify the batch is not over-reported.

Example fix

// before
endpointOpService.register(parentClientId, ns, agentName, allEndpoints); // >1000

// after
int chunkSize = 1000;
List<List<AgentEndpoint>> chunks = Lists.partition(new ArrayList<>(allEndpoints), chunkSize);
for (List<AgentEndpoint> chunk : chunks) {
    endpointOpService.register(parentClientId, ns, agentName, chunk);
}
Defensive patterns

Strategy: validation

Validate before calling

// Chunk the batch before registering
int MAX = 1000;
List<AgentEndpoint> batch = new ArrayList<>(endpoints);
if (batch.size() <= MAX) {
    endpointOpService.register(parentClientId, ns, agentName, batch);
} else {
    for (int i = 0; i < batch.size(); i += MAX) {
        List<AgentEndpoint> chunk = batch.subList(i, Math.min(i + MAX, batch.size()));
        endpointOpService.register(parentClientId, ns, agentName, chunk);
    }
}

Type guard

public static boolean isWithinBatchLimit(Collection<AgentEndpoint> endpoints) {
    return endpoints != null && endpoints.size() <= 1000;
}

Try / catch

try {
    endpointOpService.register(parentClientId, ns, agentName, endpoints);
} catch (NacosException e) {
    if (e.getCode() == NacosException.OVER_THRESHOLD) {
        // re-chunk and retry
        for (List<AgentEndpoint> chunk : partition(endpoints, 1000)) {
            endpointOpService.register(parentClientId, ns, agentName, chunk);
        }
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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