{"record":{"id":"6d3c6faf1f020457","repo":"grpc/grpc-java","slug":"client-listener-resource-name-template-clientl","errorCode":null,"errorMessage":"client_listener_resource_name_template: '${clientListnerTemplate}' does not start with ${prefix}","messagePattern":"client_listener_resource_name_template: '(.+?)' does not start with (.+?)","errorType":"exception","errorClass":"XdsInitializationException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/client/BootstrapperImpl.java","lineNumber":224,"sourceCode":"\n    Map<String, ?> rawAuthoritiesMap =\n        JsonUtil.getObject(rawData, \"authorities\");\n    ImmutableMap.Builder<String, AuthorityInfo> authorityInfoMapBuilder = ImmutableMap.builder();\n    if (rawAuthoritiesMap != null) {\n      logger.log(\n          XdsLogLevel.INFO, \"Configured with {0} xDS server authorities\", rawAuthoritiesMap.size());\n      for (String authorityName : rawAuthoritiesMap.keySet()) {\n        logger.log(XdsLogLevel.INFO, \"xDS server authority: {0}\", authorityName);\n        Map<String, ?> rawAuthority = JsonUtil.getObject(rawAuthoritiesMap, authorityName);\n        String clientListnerTemplate =\n            JsonUtil.getString(rawAuthority, \"client_listener_resource_name_template\");\n        logger.log(\n            XdsLogLevel.INFO, \"client_listener_resource_name_template: {0}\", clientListnerTemplate);\n        String prefix = XDSTP_SCHEME + \"//\" + authorityName + \"/\";\n        if (clientListnerTemplate == null) {\n          clientListnerTemplate = prefix + \"envoy.config.listener.v3.Listener/%s\";\n        } else if (!clientListnerTemplate.startsWith(prefix)) {\n          throw new XdsInitializationException(\n              \"client_listener_resource_name_template: '\" + clientListnerTemplate\n                  + \"' does not start with \" + prefix);\n        }\n        List<?> rawAuthorityServers = JsonUtil.getList(rawAuthority, \"xds_servers\");\n        List<ServerInfo> authorityServers;\n        if (rawAuthorityServers == null || rawAuthorityServers.isEmpty()) {\n          authorityServers = servers;\n        } else {\n          if (rawAuthorityServers.size() > 1 && !enableXdsFallback) {\n            rawAuthorityServers = ImmutableList.of(rawAuthorityServers.get(0));\n          }\n          authorityServers = parseServerInfos(rawAuthorityServers, logger);\n        }\n        authorityInfoMapBuilder.put(\n            authorityName, AuthorityInfo.create(clientListnerTemplate, authorityServers));\n      }\n      builder.authorities(authorityInfoMapBuilder.buildOrThrow());\n    }","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/client/BootstrapperImpl.java#L206-L242","documentation":"When parsing the 'authorities' section of a bootstrap, the per-authority 'client_listener_resource_name_template' must be an xDS-style template beginning with the 'xdstp://' scheme, the authority name, and a trailing slash (prefix = \"xdstp://<authority>/\"). Templates not starting with that prefix are rejected with XdsInitializationException.","triggerScenarios":"Setting client_listener_resource_name_template for an authority to a plain resource path (e.g. \"envoy.config.listener.v3.Listener/%s\") without the xdstp://<authority>/ prefix, or using a prefix for a different authority.","commonSituations":"Copying the top-level client_listener_resource_name_template (which uses different rules) into an authority entry; mixing templates across authorities; hand-editing multi-authority bootstrap configs for TD/federation setups.","solutions":["Rewrite the template as \"xdstp://<authority-name>/envoy.config.listener.v3.Listener/%s\", matching the authority key it is declared under.","Remove the per-authority client_listener_resource_name_template to use the default (prefix + Listener/%s).","Cross-check the authority name in the template against the key under 'authorities'."],"exampleFix":"// before\n\"authorities\": { \"foo.com\": { \"client_listener_resource_name_template\":\n  \"envoy.config.listener.v3.Listener/%s\" } }\n// after\n\"authorities\": { \"foo.com\": { \"client_listener_resource_name_template\":\n  \"xdstp://foo.com/envoy.config.listener.v3.Listener/%s\" } }","handlingStrategy":"validation","validationCode":"String tpl = authorityCfg.get(\"client_listener_resource_name_template\");\nString prefix = \"xdstp://\" + authorityName + \"/\";\nif (tpl != null && !tpl.startsWith(prefix)) {\n  throw new IllegalStateException(\n      \"authority \" + authorityName + \" template must start with \" + prefix);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Per-authority templates must be \"xdstp://<that-authority>/...\" — never reuse the top-level template format.","Generate authority config programmatically from the authority name to guarantee the prefix.","Review multi-authority bootstrap configs carefully; this field differs per authority."],"tags":["grpc","xds","bootstrap","config-validation","naming"],"backgroundTag":"invalid-config-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"}