grpc/grpc-java · error · ResourceInvalidException

Unable to unpack typedConfig for: " + typedConfig.getTypeUrl

Error message

Unable to unpack typedConfig for: " + typedConfig.getTypeUrl()

What it means

ResourceInvalidException thrown when the Any typed_config inside an LB policy extension cannot be unpacked (InvalidProtocolBufferException), i.e. the bytes don't decode into the expected Envoy/UDPA struct proto (TypedStruct, Struct, or the specific policy config type). The typeUrl advertised by the config doesn't match its actual payload.

Source

Thrown at xds/src/main/java/io/grpc/xds/LoadBalancerConfigFactory.java:252

            serviceConfig = convertRoundRobinConfig();
          } else if (typedConfig.is(LeastRequest.class)) {
            serviceConfig = convertLeastRequestConfig(typedConfig.unpack(LeastRequest.class));
          } else if (typedConfig.is(ClientSideWeightedRoundRobin.class)) {
            serviceConfig = convertWeightedRoundRobinConfig(
                typedConfig.unpack(ClientSideWeightedRoundRobin.class));
          } else if (typedConfig.is(PickFirst.class)) {
            serviceConfig = convertPickFirstConfig(typedConfig.unpack(PickFirst.class));
          } else if (typedConfig.is(com.github.xds.type.v3.TypedStruct.class)) {
            serviceConfig = convertCustomConfig(
                typedConfig.unpack(com.github.xds.type.v3.TypedStruct.class));
          } else if (typedConfig.is(com.github.udpa.udpa.type.v1.TypedStruct.class)) {
            serviceConfig = convertCustomConfig(
                typedConfig.unpack(com.github.udpa.udpa.type.v1.TypedStruct.class));
          }

          // TODO: support least_request once it is added to the envoy protos.
        } catch (InvalidProtocolBufferException e) {
          throw new ResourceInvalidException(
              "Unable to unpack typedConfig for: " + typedConfig.getTypeUrl(), e);
        }
        // The service config is expected to have a single root entry, where the name of that entry
        // is the name of the policy. A Load balancer with this name must exist in the registry.
        if (serviceConfig == null || LoadBalancerRegistry.getDefaultRegistry()
            .getProvider(Iterables.getOnlyElement(serviceConfig.keySet())) == null) {
          logger.log(XdsLogLevel.WARNING, "Policy {0} not found in the LB registry, skipping",
              typedConfig.getTypeUrl());
          continue;
        } else {
          return serviceConfig;
        }
      }

      // If we could not find a Policy that we could both convert as well as find a provider for
      // then we have an invalid LB policy configuration.
      throw new ResourceInvalidException("Invalid LoadBalancingPolicy: " + loadBalancingPolicy);
    }

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Fix the @type / type_url in the LB policy typed config on the control plane so it matches the actual message type
  2. Ensure the management server and grpc-java agree on supported extension config proto versions (upgrade one side)
  3. Log and inspect the offending resource; compare its typeUrl with the types grpc-xds supports
  4. Validate the config JSON with protoc/envoy validation before publishing to ADS

Example fix

// before: wrong @type in TypedStruct JSON
{"@type": "type.googleapis.com/wrong.pkg.Policy", ...}
// after
{"@type": "type.googleapis.com/envoy.extensions.lb.policies.round_robin.v3.RoundRobin", ...}
Defensive patterns

Strategy: validation

Validate before calling

// check typeUrl before accepting the extension config
String url = typedConfig.getTypeUrl();
boolean supported = url.endsWith("TypedStruct") || url.endsWith("Struct")
    || url.endsWith("RingHash") || url.endsWith("RoundRobin");
if (!supported) {
  throw new IllegalArgumentException("Unsupported LB extension typeUrl: " + url);
}

Try / catch

try {
  /* apply xDS cluster config */;
} catch (ResourceInvalidException e) {
  if (e.getMessage().startsWith("Unable to unpack typedConfig")) {
    logger.log(Level.WARNING, "Bad typed config from control plane: " + e.getMessage(), e);
    // reject resource; xDS will retry with a corrected one
  } else { throw e; }
}

Prevention

When it happens

Trigger: convertToServiceConfig (called from convertWrrLocalityConfig) encounters a typed extension config whose typedConfig.getTypeUrl() content fails unpack() for every supported message type.

Common situations: Control plane sets a wrong @type annotation in a TypedStruct JSON config; mismatched proto versions between management server and grpc-xds; corrupted or hand-assembled Any payloads.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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