grpc/grpc-java · error · ResourceInvalidException

Failed to parse lb config for cluster '" + cluster.getName()

Error message

Failed to parse lb config for cluster '" + cluster.getName() + "': " + configOrError.getError()

What it means

After the cluster's lb policy config map is built via LoadBalancerConfigFactory, processCluster runs it through GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig. If that returns an error, the load-balancing policy configuration for the cluster is invalid/unusable by the local gRPC LB registry and the message is wrapped in a ResourceInvalidException.

Source

Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:171

        break;
      case CLUSTERDISCOVERYTYPE_NOT_SET:
      default:
        throw new ResourceInvalidException(
            "Cluster " + cluster.getName() + ": unspecified cluster discovery type");
    }
    if (structOrError.getErrorDetail() != null) {
      throw new ResourceInvalidException(structOrError.getErrorDetail());
    }
    CdsUpdate.Builder updateBuilder = structOrError.getStruct();

    ImmutableMap<String, ?> lbPolicyConfig = LoadBalancerConfigFactory.newConfig(cluster,
        enableLeastRequest);

    NameResolver.ConfigOrError configOrError
        = GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(
            ImmutableList.of(lbPolicyConfig), loadBalancerRegistry);
    if (configOrError.getError() != null) {
      throw new ResourceInvalidException(
          "Failed to parse lb config for cluster '" + cluster.getName() + "': "
          + configOrError.getError());
    }

    updateBuilder.lbPolicyConfig(configOrError.getConfig(), lbPolicyConfig);
    updateBuilder.filterMetadata(
        ImmutableMap.copyOf(cluster.getMetadata().getFilterMetadataMap()));

    try {
      MetadataRegistry registry = MetadataRegistry.getInstance();
      ImmutableMap<String, Object> parsedFilterMetadata =
          registry.parseMetadata(cluster.getMetadata());
      updateBuilder.parsedMetadata(parsedFilterMetadata);
    } catch (ResourceInvalidException e) {
      throw new ResourceInvalidException(
          "Failed to parse xDS filter metadata for cluster '" + cluster.getName() + "': "
              + e.getMessage(), e);
    }

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Align the cluster's lb policy with a policy the client supports (e.g. round_robin or ring_hash with valid fields)
  2. Upgrade grpc-xds / generated Envoy protos to a version that recognizes the policy and fields sent by the control plane
  3. Register the missing custom LoadBalancer provider on the client if a custom policy is intended

Example fix

// before
{"leastRequest": {"choiceCount": -1}}
// after
{"leastRequest": {"choiceCount": 2}}
Defensive patterns

Strategy: validation

Validate before calling

NameResolver.ConfigOrError check = GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(
    ImmutableList.of(lbPolicyConfig), loadBalancerRegistry);
if (check.getError() != null) {
  throw new IllegalArgumentException("Invalid lb config: " + check.getError());
}

Try / catch

try {
  cdsUpdate = xdsClusterResource.parseResource(args);
} catch (ResourceInvalidException e) {
  if (e.getMessage().contains("Failed to parse lb config")) {
    // fall back to round_robin or fix control-plane policy
  }
}

Prevention

When it happens

Trigger: A Cluster advertises an lb policy (round_robin, least_request, ring_hash, etc.) whose generated config fails local parsing — e.g. unsupported child policy name, malformed policy JSON, or a policy not registered in the local LoadBalancer registry.

Common situations: Control plane sends custom or newer LB policies the client doesn't support; least_request/ring_hash config fields from a newer Envoy API than the client's protobuf version; typo'd policy name in cluster config.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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