{"record":{"id":"3811c927403d5d98","repo":"grpc/grpc-java","slug":"invalid-message-type-unpackedmessage-getclass-3811c9","errorCode":null,"errorMessage":"Invalid message type: ${unpackedMessage.getClass()}","messagePattern":"Invalid message type: (.+?)","errorType":"validation","errorClass":"ResourceInvalidException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/XdsListenerResource.java","lineNumber":106,"sourceCode":"  public String typeUrl() {\n    return ADS_TYPE_URL_LDS;\n  }\n\n  @Override\n  public boolean shouldRetrieveResourceKeysForArgs() {\n    return false;\n  }\n\n  @Override\n  protected boolean isFullStateOfTheWorld() {\n    return true;\n  }\n\n  @Override\n  protected LdsUpdate doParse(Args args, Message unpackedMessage)\n      throws ResourceInvalidException {\n    if (!(unpackedMessage instanceof Listener)) {\n      throw new ResourceInvalidException(\"Invalid message type: \" + unpackedMessage.getClass());\n    }\n    Listener listener = (Listener) unpackedMessage;\n\n    if (listener.hasApiListener()) {\n      return processClientSideListener(listener, args);\n    } else {\n      return processServerSideListener(listener, args);\n    }\n  }\n\n  private LdsUpdate processClientSideListener(Listener listener, XdsResourceType.Args args)\n      throws ResourceInvalidException {\n    // Unpack HttpConnectionManager from the Listener.\n    HttpConnectionManager hcm;\n    try {\n      hcm = unpackCompatibleType(\n          listener.getApiListener().getApiListener(), HttpConnectionManager.class,\n          TYPE_URL_HTTP_CONNECTION_MANAGER, null);","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/XdsListenerResource.java#L88-L124","documentation":"The LDS (Listener) resource parser doParse expects the Any in a Listener resource to unpack to envoy.config.listener.v3.Listener. If the unpacked message is any other type, the resource is rejected with 'Invalid message type: <class>'. This guards against a management server serving the wrong resource under the Listener type URL.","triggerScenarios":"An xDS response for the ListenerService/LdsResource type URL contains a message that is not a Listener (e.g. a RouteConfiguration or Cluster packed under the LDS type URL, or a v2 Listener with mismatched type_url mapping); doParse's instanceof check fails.","commonSituations":"Misconfigured management server mapping resource names to the wrong types; ADS multiplexing sending resources to the wrong stream type; custom servers hand-building DiscoveryResponses with wrong Any contents; v2/v3 type-URL skew.","solutions":["Verify the management server sends envoy.config.listener.v3.Listener messages for LDS resources","Check that each Any's type_url corresponds to the Listener resource type","Fix ADS routing so Listener resources are not delivered under another type's subscription","Compare control plane and client xDS versions (v2 vs v3 type URLs) and align them"],"exampleFix":"// before (wrong message under LDS type_url)\nresources { any { type_url: \"type.googleapis.com/envoy.config.route.v3.RouteConfiguration\" ... } }\n// after\nresources { any { type_url: \"type.googleapis.com/envoy.config.listener.v3.Listener\" ... } }","handlingStrategy":"validation","validationCode":"// Control-plane side: assert LDS payloads are Listener messages\nfor (com.google.protobuf.Any any : discoveryResponse.getResourcesList()) {\n  try {\n    if (!(any.unpack(io.envoyproxy.envoy.config.listener.v3.Listener.class)\n        instanceof io.envoyproxy.envoy.config.listener.v3.Listener)) {\n      throw new IllegalStateException(\"Non-Listener resource in LDS response\");\n    }\n  } catch (InvalidProtocolBufferException e) {\n    throw new IllegalStateException(\"Bad LDS resource: \" + any.getTypeUrl(), e);\n  }\n}","typeGuard":"boolean isListenerResource(com.google.protobuf.Any any) {\n  try {\n    return any.is(io.envoyproxy.envoy.config.listener.v3.Listener.class);\n  } catch (InvalidProtocolBufferException e) {\n    return false;\n  }\n}","tryCatchPattern":"// Client side: detect wrong-type LDS payloads from watcher errors\n@Override public void onError(Status error) {\n  if (error.getDescription().startsWith(\"Invalid message type:\")) {\n    logger.log(WARNING, \"LDS response carried wrong message type: \" + error.getDescription());\n  }\n}","preventionTips":["Verify management-server resource-to-type-URL mapping for LDS","Use Any.pack(listener) rather than hand-built Any messages","Check ADS routing so Listener subscriptions only receive Listener resources","Align v2/v3 xDS type URLs across control plane and client"],"tags":["grpc","xds","lds","protobuf","type-mismatch"],"backgroundTag":"type-mismatch","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"}