grpc/grpc-java · error · ResourceInvalidException
Could not parse HttpConnectionManager config from…
Error message
Could not parse HttpConnectionManager config from ApiListener
What it means
For client-side (api_listener-based) Listeners, gRPC unpacks the ApiListener's api_listener Any into an HttpConnectionManager. If the Any cannot be unpacked (wrong type URL or invalid bytes), the Listener is rejected with 'Could not parse HttpConnectionManager config from ApiListener'.
Solutions
- Ensure api_listener Any carries an HttpConnectionManager message with the correct v3 type URL
- Inspect the Any type_url from the management server to confirm what was packed
- Fix proto version skew between control plane and gRPC client (v3 HCM expected)
- Re-serialize and re-push the corrected Listener resource
Example fix
// before
api_listener { api_listener { type_url: "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HcmConfig" ... } }
// after
api_listener { api_listener { type_url: "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager" ... } } Defensive patterns
Strategy: validation
Validate before calling
// Control-plane side: ensure api_listener Any unpacks to HttpConnectionManager
try {
listener.getApiListener().getApiListener()
.unpack(io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.class);
} catch (InvalidProtocolBufferException e) {
throw new IllegalStateException("ApiListener is not an HCM: "
+ listener.getApiListener().getApiListener().getTypeUrl(), e);
} Type guard
boolean isHttpConnectionManagerAny(com.google.protobuf.Any any) {
try {
return any.is(io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.class);
} catch (InvalidProtocolBufferException e) {
return false;
}
} Try / catch
// Client side: flag unparseable ApiListener configs from watcher errors
@Override public void onError(Status error) {
if (error.getDescription().contains("Could not parse HttpConnectionManager config from ApiListener")) {
logger.log(WARNING, "Bad api_listener in LDS resource: " + error.getDescription());
}
} Prevention
- Pack the HCM with Any.pack(httpConnectionManager) to guarantee the correct type_url
- Confirm the control plane does not wrap other network filters where HCM is required
- Keep envoy extensions protos (HCM) version-aligned with the client
- Test LDS payloads against grpc-java xDS interop tests before rollout
When it happens
Trigger: Listener.api_listener.api_listener Any does not decode to envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager (wrong type_url such as an HCM filter chain or a different filter config, or malformed serialized bytes); unpackCompatibleType throws InvalidProtocolBufferException.
Common situations: Control plane serves a filter-chain config where an HttpConnectionManager is expected; hand-written bootstrap/LDS payloads with wrong Any contents; proto version skew producing incompatible serialized HCM.
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
- Invalid message type
- ClusterSpecifierPlugin
- Failed to parse metadata key
- Invalid address: Empty address is not allowed.
- Invalid message type: " + unpackedMessage.getClass()
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/6b6b1148c0e338b6.
Report an issue: GitHub.
Appendix: source
Thrown at xds/src/main/java/io/grpc/xds/XdsListenerResource.java:126
Listener listener = (Listener) unpackedMessage;
if (listener.hasApiListener()) {
return processClientSideListener(listener, args);
} else {
return processServerSideListener(listener, args);
}
}
private LdsUpdate processClientSideListener(Listener listener, XdsResourceType.Args args)
throws ResourceInvalidException {
// Unpack HttpConnectionManager from the Listener.
HttpConnectionManager hcm;
try {
hcm = unpackCompatibleType(
listener.getApiListener().getApiListener(), HttpConnectionManager.class,
TYPE_URL_HTTP_CONNECTION_MANAGER, null);
} catch (InvalidProtocolBufferException e) {
throw new ResourceInvalidException(
"Could not parse HttpConnectionManager config from ApiListener", e);
}
return LdsUpdate.forApiListener(
parseHttpConnectionManager(hcm, filterRegistry, true /* isForClient */, args));
}
private LdsUpdate processServerSideListener(Listener proto, XdsResourceType.Args args)
throws ResourceInvalidException {
Set<String> certProviderInstances = null;
if (args.getBootstrapInfo() != null && args.getBootstrapInfo().certProviders() != null) {
certProviderInstances = args.getBootstrapInfo().certProviders().keySet();
}
return LdsUpdate.forTcpListener(parseServerSideListener(proto,
(TlsContextManager) args.getSecurityConfig(),
filterRegistry, certProviderInstances, args));
}
@VisibleForTestingView on GitHub (pinned to 64daddc1f3)