alibaba/nacos · error · IllegalArgumentException
Management or declared Endpoint forbids healthy
Error message
Management or declared Endpoint forbids healthy
What it means
Thrown by validateEndpoint when a declared or management Endpoint has a non-null healthy field. The healthy flag is reserved for runtime snapshots (RuntimeEndpointSnapshotItem carries its own enabled/healthy/state); declared endpoints on an AgentCallInterface are static configuration and must not embed a health opinion, so Endpoint.getHealthy() must be null for them. The check runs after EndpointCanonicalizer.canonicalize, so it inspects the (copied) endpoint value.
Source
Thrown at api/src/main/java/com/alibaba/nacos/api/ai/utils/AgentModelValidator.java:619
RuntimeEndpointState expected;
if (!item.getEnabled()) {
expected = RuntimeEndpointState.DISABLED;
} else if (!item.getHealthy()) {
expected = RuntimeEndpointState.UNHEALTHY;
} else {
expected = RuntimeEndpointState.AVAILABLE;
}
if (item.getState() != expected) {
throw new IllegalArgumentException(
"Runtime Endpoint state must be " + expected.name());
}
}
private static void validateEndpoint(Endpoint endpoint) {
requireNonNull(endpoint, "Endpoint");
EndpointCanonicalizer.canonicalize(endpoint);
if (endpoint.getHealthy() != null) {
throw new IllegalArgumentException("Management or declared Endpoint forbids healthy");
}
}
private static void validateAbsoluteUri(String value, String fieldName) {
if (value.isEmpty() || codePointLength(value) > MAX_URI_LENGTH) {
throw new IllegalArgumentException("Invalid " + fieldName + ": " + value);
}
try {
URI uri = new URI(value);
if (!uri.isAbsolute()) {
throw new IllegalArgumentException("Invalid " + fieldName + ": " + value);
}
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid " + fieldName + ": " + value, e);
}
}
private static void validateRequiredLength(String value, int maximum, String fieldName) {View on GitHub (pinned to 9b989acdf1)
Solutions
- Set healthy to null on every Endpoint you put into declaredEndpoints (or simply never set it).
- Keep runtime health on RuntimeEndpointSnapshotItem.enabled/healthy/state, never on the Endpoint value used in declared lists.
- If you share an Endpoint type between declared and runtime contexts, clear healthy before adding to declaredEndpoints.
- Build declared endpoints from a factory that never touches the healthy setter.
Example fix
// before
Endpoint e = new Endpoint();
e.setUri("grpc://svc:8080");
e.setHealthy(true); // forbidden on declared endpoint -> rejected
callInterface.setDeclaredEndpoints(List.of(e));
// after
Endpoint e = new Endpoint();
e.setUri("grpc://svc:8080"); // healthy stays null
callInterface.setDeclaredEndpoints(List.of(e)); Defensive patterns
Strategy: validation
Validate before calling
for (AgentCallInterface ci : agent.getCallInterfaces()) {
List<Endpoint> eps = ci.getDeclaredEndpoints();
if (eps == null) continue;
for (Endpoint e : eps) {
if (e.getHealthy() != null) {
throw new IllegalStateException("declared endpoint must not set healthy: " + e.getUri());
}
}
} Type guard
static boolean declaredEndpointsHealthyFree(List<Endpoint> eps) {
if (eps == null) return true;
for (Endpoint e : eps) if (e.getHealthy() != null) return false;
return true;
} Try / catch
try {
AgentModelValidator.validateAgent(agent);
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("Management or declared Endpoint forbids healthy")) {
// null out healthy on each declared endpoint and retry
} else throw e;
} Prevention
- Never call setHealthy on an Endpoint used in declaredEndpoints.
- Keep runtime health on RuntimeEndpointSnapshotItem.enabled/healthy/state.
- If reusing Endpoint objects across contexts, clear healthy before adding to declared lists.
When it happens
Trigger: Any declared endpoint list (AgentCallInterface.getDeclaredEndpoints()) or management endpoint that includes a non-null healthy value, submitted through Agent publish/update via validateAgent. validateEndpoint is also used for runtime items' Endpoint but there healthy is set on the item, not the Endpoint — so this specifically catches healthy being wrongly placed on the Endpoint value.
Common situations: Reusing a runtime snapshot Endpoint object (which had healthy set) as a declared endpoint; a shared DTO that defaults healthy=true; copy-pasting from a health-bearing model into the declared-endpoint model; an ORM/serializer that materializes healthy from a default.
Related errors
- declaredEndpoints exceeds {MAX_DECLARED_ENDPOINTS} items
- Duplicate declared Endpoint: {key}
- Duplicate runtime Endpoint: {endpointKey}
- 20002
- 10000
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/ed12c5bdd4d831b4.
Report an issue: GitHub.