{"record":{"id":"83388e834c45d2dc","repo":"grpc/grpc-java","slug":"untrusted-xds-server-uri-not-found-in-allowed-gr","errorCode":null,"errorMessage":"Untrusted xDS server & URI not found in allowed_grpc_services: \" + targetUri","messagePattern":"Untrusted xDS server & URI not found in allowed_grpc_services: \" \\+ targetUri","errorType":"validation","errorClass":"GrpcServiceParseException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java","lineNumber":173,"sourceCode":"      String scheme = uri.getScheme();\n      if (scheme == null) {\n        scheme = NameResolverRegistry.getDefaultRegistry().getDefaultScheme();\n      }\n      if (scheme != null) {\n        isTargetUriSchemeSupported =\n            NameResolverRegistry.getDefaultRegistry().getProviderForScheme(scheme) != null;\n      }\n    } catch (URISyntaxException e) {\n      // Fallback or ignore if not a valid URI\n    }\n\n    if (!isTargetUriSchemeSupported) {\n      throw new GrpcServiceParseException(\"Target URI scheme is not resolvable: \" + targetUri);\n    }\n\n    if (!isTrustedControlPlane) {\n      if (!override.isPresent()) {\n        throw new GrpcServiceParseException(\n            \"Untrusted xDS server & URI not found in allowed_grpc_services: \" + targetUri);\n      }\n\n      GrpcServiceConfig.GoogleGrpcConfig.Builder builder =\n          GrpcServiceConfig.GoogleGrpcConfig.builder().target(targetUri)\n              .configuredChannelCredentials(override.get().configuredChannelCredentials());\n      if (override.get().callCredentials().isPresent()) {\n        builder.callCredentials(override.get().callCredentials().get());\n      }\n      return builder.build();\n    }\n\n    ConfiguredChannelCredentials channelCreds =\n        extractChannelCredentials(googleGrpcProto.getChannelCredentialsPluginList());\n\n    Optional<CallCredentials> callCreds =\n        extractCallCredentials(googleGrpcProto.getCallCredentialsPluginList());\n","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java#L155-L191","documentation":"Thrown by GrpcServiceConfigParser.parseGoogleGrpcConfig when the xDS server is not marked trusted in the bootstrap (isTrustedControlPlane is false) and the target URI has no override entry in allowed_grpc_services. As a security measure, untrusted control planes may only reference target URIs explicitly allow-listed with their own channel credentials in the bootstrap file.","triggerScenarios":"Bootstrap server_info lacks the trusted marker while an LDS/CDS resource references a google_grpc target_uri that is absent from bootstrap.allowed_grpc_services, so no override credentials are found and parsing aborts.","commonSituations":"Multi-tenant setups where the control plane pushes URIs the operator never allow-listed; forgetting to add a new target URI to allowed_grpc_services after a control-plane change; misconfigured 'server_info' trust settings in the bootstrap.","solutions":["Add the target URI to allowed_grpc_services in the bootstrap file with proper channel_creds for it.","If the control plane is genuinely trusted (e.g. Google's), mark the server as trusted in the bootstrap so the allow-list check is bypassed.","Compare the target_uri in the failing xDS resource against the bootstrap's allowed_grpc_services keys for typos."],"exampleFix":"// before (bootstrap.json)\n\"allowed_grpc_services\": {}\n// after\n\"allowed_grpc_services\": {\"trafficdirector.googleapis.com\": {\"channel_creds\": [{\"type\": \"google_default\"}]}}","handlingStrategy":"validation","validationCode":"// Pre-check: every URI pushed by an untrusted control plane must be allow-listed\nif (!bootstrapInfo.servers().get(0).isTrusted()) {\n  for (String uri : pushedTargetUris) {\n    if (!allowedGrpcServices.containsKey(uri)) {\n      throw new IllegalArgumentException(\"URI not in allowed_grpc_services: \" + uri);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  config = GrpcServiceConfigParser.parse(proto, bootstrapInfo, serverInfo);\n} catch (GrpcServiceParseException e) {\n  if (e.getMessage().contains(\"allowed_grpc_services\")) {\n    // reject resource; update bootstrap allow-list before retrying\n  }\n}","preventionTips":["Keep allowed_grpc_services in sync with every URI your control plane can push","Mark the server trusted in the bootstrap only when it is genuinely trusted","Audit bootstrap allow-list entries whenever control-plane targets change"],"tags":["xds","security","bootstrap","allowlist"],"backgroundTag":"permission-denied","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"}