grpc/grpc-java · error · ResourceInvalidException

${structOrError.getErrorDetail()}

Error message

${structOrError.getErrorDetail()}

What it means

While processing a ClusterLoadAssignment, each LocalityLbEndpoints is parsed via parseLocalityLbEndpoints, which returns a StructOrError. If that struct carries an errorDetail (the locality's own validation failed, e.g. missing locality, bad load balancer weight or sockets), processClusterLoadAssignment rethrows it as a ResourceInvalidException, failing the whole EDS resource.

Source

Thrown at xds/src/main/java/io/grpc/xds/XdsEndpointResource.java:129

  private static boolean isEnabledXdsDualStack() {
    return GrpcUtil.getFlag(GRPC_EXPERIMENTAL_XDS_DUALSTACK_ENDPOINTS, false);
  }

  private static EdsUpdate processClusterLoadAssignment(ClusterLoadAssignment assignment)
      throws ResourceInvalidException {
    Map<Integer, Set<Locality>> priorities = new HashMap<>();
    Map<Locality, LocalityLbEndpoints> localityLbEndpointsMap = new LinkedHashMap<>();
    List<Endpoints.DropOverload> dropOverloads = new ArrayList<>();
    int maxPriority = -1;
    for (io.envoyproxy.envoy.config.endpoint.v3.LocalityLbEndpoints localityLbEndpointsProto
        : assignment.getEndpointsList()) {
      StructOrError<LocalityLbEndpoints> structOrError =
          parseLocalityLbEndpoints(localityLbEndpointsProto);
      if (structOrError == null) {
        continue;
      }
      if (structOrError.getErrorDetail() != null) {
        throw new ResourceInvalidException(structOrError.getErrorDetail());
      }

      LocalityLbEndpoints localityLbEndpoints = structOrError.getStruct();
      int priority = localityLbEndpoints.priority();
      maxPriority = Math.max(maxPriority, priority);
      // Note endpoints with health status other than HEALTHY and UNKNOWN are still
      // handed over to watching parties. It is watching parties' responsibility to
      // filter out unhealthy endpoints. See EnvoyProtoData.LbEndpoint#isHealthy().
      Locality locality =  parseLocality(localityLbEndpointsProto.getLocality());
      localityLbEndpointsMap.put(locality, localityLbEndpoints);
      if (!priorities.containsKey(priority)) {
        priorities.put(priority, new HashSet<>());
      }
      if (!priorities.get(priority).add(locality)) {
        throw new ResourceInvalidException("ClusterLoadAssignment has duplicate locality:"
            + locality + " for priority:" + priority);
      }
    }

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Read the errorDetail text — it names the specific locality field that failed validation
  2. Fix the offending LocalityLbEndpoints in the management server's EDS output
  3. Ensure each locality has a valid Locality (region/zone/sub_zone) and valid endpoints
  4. Test EDS payloads with grpc-java xDS interop tests before deploying
Defensive patterns

Strategy: try-catch

Validate before calling

for (LocalityLbEndpoints lle : assignment.getEndpointsList()) {
  if (!lle.hasLocality()) throw new IllegalArgumentException("locality missing in EDS payload");
  if (lle.getLbEndpointsCount() == 0) throw new IllegalArgumentException("empty locality");
}

Try / catch

try {
  update = XdsEndpointResource.getInstance().parse(args, resource);
} catch (ResourceInvalidException e) {
  logger.warn("EDS rejected: {}", e.getMessage()); // errorDetail names the bad locality field
}

Prevention

When it happens

Trigger: An EDS ClusterLoadAssignment contains a locality whose LocalityLbEndpoints fails per-locality validation — e.g. missing locality field, invalid endpoint address/port, or bad lb_endpoints entries — surfacing the inner error message.

Common situations: Control plane generating malformed endpoints for a locality; partially-populated LocalityLbEndpoints from service discovery backends; hand-written EDS test fixtures with missing fields.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/641c425005f8acbf. Report an issue: GitHub.