{"record":{"id":"20d6a9f40094997f","repo":"grpc/grpc-java","slug":"unsupported-fallback-credentials-type-for-xdscrede","errorCode":null,"errorMessage":"Unsupported fallback credentials type for XdsCredentials","messagePattern":"Unsupported fallback credentials type for XdsCredentials","errorType":"validation","errorClass":"GrpcServiceParseException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java","lineNumber":218,"sourceCode":"\n  private static Optional<ConfiguredChannelCredentials> channelCredsFromProto(Any cred)\n      throws GrpcServiceParseException {\n    String typeUrl = cred.getTypeUrl();\n    try {\n      switch (typeUrl) {\n        case GOOGLE_DEFAULT_CREDENTIALS_TYPE_URL:\n          return Optional\n              .of(ConfiguredChannelCredentials.create(GoogleDefaultChannelCredentials.create(),\n                  new ProtoChannelCredsConfig(typeUrl, cred)));\n        case INSECURE_CREDENTIALS_TYPE_URL:\n          return Optional.of(ConfiguredChannelCredentials.create(\n              InsecureChannelCredentials.create(), new ProtoChannelCredsConfig(typeUrl, cred)));\n        case XDS_CREDENTIALS_TYPE_URL:\n          XdsCredentials xdsConfig = cred.unpack(XdsCredentials.class);\n          Optional<ConfiguredChannelCredentials> fallbackCreds =\n              channelCredsFromProto(xdsConfig.getFallbackCredentials());\n          if (!fallbackCreds.isPresent()) {\n            throw new GrpcServiceParseException(\n                \"Unsupported fallback credentials type for XdsCredentials\");\n          }\n          return Optional.of(ConfiguredChannelCredentials.create(\n              XdsChannelCredentials.create(fallbackCreds.get().channelCredentials()),\n              new ProtoChannelCredsConfig(typeUrl, cred)));\n        case LOCAL_CREDENTIALS_TYPE_URL:\n          throw new GrpcServiceParseException(\n              \"LocalCredentials are not supported in grpc-java. \"\n                  + \"See https://github.com/grpc/grpc-java/issues/8928\");\n        case TLS_CREDENTIALS_TYPE_URL:\n          // For this PR, we establish this structural skeleton,\n          // but throw an GrpcServiceParseException until the exact stream conversions are\n          // merged.\n          throw new GrpcServiceParseException(\n              \"TlsCredentials input stream construction pending.\");\n        default:\n          return Optional.empty();\n      }","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java#L200-L236","documentation":"Thrown by GrpcServiceConfigParser.channelCredsFromProto when unwrapping an XdsCredentials proto whose fallback_credentials field is present but of an unsupported type — the recursive channelCredsFromProto call returns Optional.empty(). XdsChannelCredentials requires a usable fallback credential; without one the credentials block cannot be constructed.","triggerScenarios":"xDS resource contains credentials with xds_credentials_type whose fallback_credentials is unset in a way that yields empty (unsupported type_url, missing oneof case, or a type not in the parser's switch: TLS, insecure, xds, local), so fallbackCreds.isPresent() is false.","commonSituations":"Control plane sending fallback credentials of a type grpc-java doesn't implement (e.g. Envoy-only credential types); proto with the fallback oneof left empty while the type implies xds credentials; version skew where newer credential proto types are unknown to the client.","solutions":["Set fallback_credentials to a supported type (TLS with root certs, or insecure) in the xds_credentials message.","Upgrade grpc-java if the fallback credential type is newer than the client's supported set.","Inspect the sent credentials proto (type_url of the fallback Any) to confirm which case the parser lacks.","If TLS fallback is intended, populate the tls_credentials_type with a valid certificate provider config."],"exampleFix":"// before (xDS resource)\nxds_credentials { fallback_credentials { } }\n// after\nxds_credentials { fallback_credentials { tls_credentials_type { certificate_provider_instance { name: \"google_mesh_ca\" } } } }","handlingStrategy":"validation","validationCode":"// Check fallback credentials are a supported type before accepting the resource\nif (cred.getTypeUrl().equals(XDS_CREDENTIALS_TYPE_URL)) {\n  XdsCredentials x = cred.unpack(XdsCredentials.class);\n  if (!channelCredsFromProto(x.getFallbackCredentials()).isPresent()) {\n    throw new IllegalArgumentException(\"xds credentials need a supported fallback (TLS/insecure)\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  Optional<ConfiguredChannelCredentials> creds = channelCredsFromProto(cred);\n} catch (GrpcServiceParseException e) {\n  if (e.getMessage().contains(\"fallback credentials\")) {\n    logger.log(WARNING, \"Unsupported fallback creds in xDS resource: \" + e.getMessage());\n    // fall back to bootstrap-level credentials\n  }\n}","preventionTips":["Always populate xds_credentials.fallback_credentials with TLS or insecure","Keep grpc-java upgraded to support newer credential proto types","Log unrecognized credential type_urls on the control plane for early detection"],"tags":["xds","credentials","protobuf","unsupported"],"backgroundTag":"unsupported-enum-value","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"}