{"record":{"id":"641c425005f8acbf","repo":"grpc/grpc-java","slug":"structorerror-geterrordetail-641c42","errorCode":null,"errorMessage":"${structOrError.getErrorDetail()}","messagePattern":"\\$\\{structOrError\\.getErrorDetail\\(\\)\\}","errorType":"validation","errorClass":"ResourceInvalidException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/XdsEndpointResource.java","lineNumber":129,"sourceCode":"  private static boolean isEnabledXdsDualStack() {\n    return GrpcUtil.getFlag(GRPC_EXPERIMENTAL_XDS_DUALSTACK_ENDPOINTS, false);\n  }\n\n  private static EdsUpdate processClusterLoadAssignment(ClusterLoadAssignment assignment)\n      throws ResourceInvalidException {\n    Map<Integer, Set<Locality>> priorities = new HashMap<>();\n    Map<Locality, LocalityLbEndpoints> localityLbEndpointsMap = new LinkedHashMap<>();\n    List<Endpoints.DropOverload> dropOverloads = new ArrayList<>();\n    int maxPriority = -1;\n    for (io.envoyproxy.envoy.config.endpoint.v3.LocalityLbEndpoints localityLbEndpointsProto\n        : assignment.getEndpointsList()) {\n      StructOrError<LocalityLbEndpoints> structOrError =\n          parseLocalityLbEndpoints(localityLbEndpointsProto);\n      if (structOrError == null) {\n        continue;\n      }\n      if (structOrError.getErrorDetail() != null) {\n        throw new ResourceInvalidException(structOrError.getErrorDetail());\n      }\n\n      LocalityLbEndpoints localityLbEndpoints = structOrError.getStruct();\n      int priority = localityLbEndpoints.priority();\n      maxPriority = Math.max(maxPriority, priority);\n      // Note endpoints with health status other than HEALTHY and UNKNOWN are still\n      // handed over to watching parties. It is watching parties' responsibility to\n      // filter out unhealthy endpoints. See EnvoyProtoData.LbEndpoint#isHealthy().\n      Locality locality =  parseLocality(localityLbEndpointsProto.getLocality());\n      localityLbEndpointsMap.put(locality, localityLbEndpoints);\n      if (!priorities.containsKey(priority)) {\n        priorities.put(priority, new HashSet<>());\n      }\n      if (!priorities.get(priority).add(locality)) {\n        throw new ResourceInvalidException(\"ClusterLoadAssignment has duplicate locality:\"\n            + locality + \" for priority:\" + priority);\n      }\n    }","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/XdsEndpointResource.java#L111-L147","documentation":"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.","triggerScenarios":"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.","commonSituations":"Control plane generating malformed endpoints for a locality; partially-populated LocalityLbEndpoints from service discovery backends; hand-written EDS test fixtures with missing fields.","solutions":["Read the errorDetail text — it names the specific locality field that failed validation","Fix the offending LocalityLbEndpoints in the management server's EDS output","Ensure each locality has a valid Locality (region/zone/sub_zone) and valid endpoints","Test EDS payloads with grpc-java xDS interop tests before deploying"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"for (LocalityLbEndpoints lle : assignment.getEndpointsList()) {\n  if (!lle.hasLocality()) throw new IllegalArgumentException(\"locality missing in EDS payload\");\n  if (lle.getLbEndpointsCount() == 0) throw new IllegalArgumentException(\"empty locality\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  update = XdsEndpointResource.getInstance().parse(args, resource);\n} catch (ResourceInvalidException e) {\n  logger.warn(\"EDS rejected: {}\", e.getMessage()); // errorDetail names the bad locality field\n}","preventionTips":["Validate each LocalityLbEndpoints (locality present, endpoints valid) before sending","Fix the field named in errorDetail at the management server","Run xDS interop tests on EDS payloads"],"tags":["xds","eds","protobuf","validation","grpc-java"],"backgroundTag":"schema-validation-failed","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}