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
- Deduplicate the protocols list before submission using a LinkedHashSet.
- Normalize protocol strings to the canonical lowercase form before dedup.
- 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
- Deduplicate protocol lists with a LinkedHashSet before submission.
- Normalize protocol strings to canonical lowercase before dedup.
- Audit code that composes protocol lists from multiple sources.
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
- Duplicate tag: {tag}
- Duplicate Version label: {label}
- {fieldName} must contain 1 to {MAX_CALL_INTERFACES} values
- Duplicate CallInterface protocol: {callInterface.protocol}
- Duplicate Endpoint source: {source}
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/b07034fb285692d2.
Report an issue: GitHub.