alibaba/nacos · error · IllegalArgumentException

Duplicate protocol: {protocol}

Error message

Duplicate protocol: {protocol}

What it means

Thrown by validateProtocols when the same protocol string appears more than once in a protocols list. Protocols within one list must be unique; duplicates would create ambiguous call-interface resolution. This runs after per-protocol format validation (AgentValidationUtils.validateProtocol) and the size check.

Source

Thrown at api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java:495

        for (String label : labels) {
            AgentValidationUtils.validateNonLatestLabel(label);
            if (!entryLabels.add(label) || !allLabels.add(label)) {
                throw new IllegalArgumentException("Duplicate Version label: " + label);
            }
        }
    }
    
    private static void validateProtocols(List<String> protocols, String fieldName) {
        requireNonNull(protocols, fieldName);
        if (protocols.isEmpty() || protocols.size() > MAX_CALL_INTERFACES) {
            throw new IllegalArgumentException(
                fieldName + " must contain 1 to " + MAX_CALL_INTERFACES + " values");
        }
        Set<String> uniqueProtocols = new HashSet<String>();
        for (String protocol : protocols) {
            AgentValidationUtils.validateProtocol(protocol);
            if (!uniqueProtocols.add(protocol)) {
                throw new IllegalArgumentException("Duplicate protocol: " + protocol);
            }
        }
    }
    
    private static void validateCallInterfaces(String namespaceId, String agentName,
        List<AgentCallInterface> callInterfaces) {
        requireNonNull(callInterfaces, "callInterfaces");
        if (callInterfaces.isEmpty() || callInterfaces.size() > MAX_CALL_INTERFACES) {
            throw new IllegalArgumentException(
                "callInterfaces must contain 1 to " + MAX_CALL_INTERFACES + " items");
        }
        Set<String> protocols = new HashSet<String>();
        for (AgentCallInterface callInterface : callInterfaces) {
            validateCallInterface(namespaceId, agentName, callInterface);
            if (!protocols.add(callInterface.getProtocol())) {
                throw new IllegalArgumentException(
                    "Duplicate CallInterface protocol: " + callInterface.getProtocol());
            }

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Deduplicate the protocols list before submission using a LinkedHashSet.
  2. Normalize protocol strings to the canonical lowercase form before dedup.
  3. Audit code that composes protocol lists from multiple sources.

Example fix

// before
entry.setProtocols(List.of("mcp", "a2a", "mcp"));
// after
entry.setProtocols(new ArrayList<>(new LinkedHashSet<>(List.of("mcp", "a2a", "mcp"))));
Defensive patterns

Strategy: validation

Validate before calling

static List<String> dedupProtocols(List<String> protocols) {
    return new ArrayList<>(new LinkedHashSet<>(protocols));
}

Type guard

static boolean protocolsAreUnique(List<String> protocols) {
    return protocols == null || new HashSet<>(protocols).size() == protocols.size();
}

Try / catch

try {
    AgentModelValidator.validateAgent(agent);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Duplicate protocol")) {
        // dedup the offending protocols list
    }
}

Prevention

When it happens

Trigger: A catalog entry protocols list containing ["mcp", "a2a", "mcp"]. Concatenating default and override protocol lists without dedup.

Common situations: Merging a base protocol set with per-environment additions that re-include a base protocol; case mismatch is NOT caught here (exact match), so "MCP" and "mcp" would both pass but collide downstream.

Related errors


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