{"record":{"id":"583709e0f435355e","repo":"grpc/grpc-java","slug":"nameresolverregistry-is-not-set-in-builder","errorCode":null,"errorMessage":"NameResolverRegistry is not set in Builder","messagePattern":"NameResolverRegistry is not set in Builder","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/grpc/NameResolver.java","lineNumber":525,"sourceCode":"      return overrideAuthority;\n    }\n\n    /**\n     * Returns the {@link MetricRecorder} that the channel uses to record metrics.\n     */\n    public MetricRecorder getMetricRecorder() {\n      return metricRecorder;\n    }\n\n    /**\n     * Returns the {@link NameResolverRegistry} that the Channel uses to look for {@link\n     * NameResolver}s.\n     *\n     * @since 1.74.0\n     */\n    public NameResolverRegistry getNameResolverRegistry() {\n      if (nameResolverRegistry == null) {\n        throw new IllegalStateException(\"NameResolverRegistry is not set in Builder\");\n      }\n      return nameResolverRegistry;\n    }\n\n    @Override\n    public String toString() {\n      return MoreObjects.toStringHelper(this)\n          .add(\"defaultPort\", defaultPort)\n          .add(\"proxyDetector\", proxyDetector)\n          .add(\"syncContext\", syncContext)\n          .add(\"serviceConfigParser\", serviceConfigParser)\n          .add(\"customArgs\", customArgs)\n          .add(\"scheduledExecutorService\", scheduledExecutorService)\n          .add(\"channelLogger\", channelLogger)\n          .add(\"executor\", executor)\n          .add(\"overrideAuthority\", overrideAuthority)\n          .add(\"metricRecorder\", metricRecorder)\n          .add(\"nameResolverRegistry\", nameResolverRegistry)","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/api/src/main/java/io/grpc/NameResolver.java#L507-L543","documentation":"NameResolver.Args.Builder.getNameResolverRegistry() throws IllegalStateException when nameResolverRegistry was never set via setNameResolverRegistry(). The registry (experimental since 1.74.0) lets a NameResolver look up nested providers to create child resolvers. Accessing it on Args built without it is an invariant violation: gRPC always sets this field when constructing Args internally, so null indicates the Args came from incomplete custom code.","triggerScenarios":"Calling getNameResolverRegistry() on NameResolver.Args whose Builder lacked a setNameResolverRegistry(...) call — e.g. inside a custom NameResolverProvider.newNameResolver that reads the registry, while the Args were assembled by test code or an older builder invocation that predates the 1.74.0 field.","commonSituations":"Custom NameResolver implementations that delegate to child resolvers via the registry; unit tests building Args manually; mixing gRPC versions where an integration layer (e.g. grpc-xds or a third-party resolver) builds Args without the registry field set.","solutions":["Add setNameResolverRegistry(NameResolverRegistry.getDefaultRegistry()) or the channel-provided registry on the Args.Builder before build()","If you don't need the registry, avoid calling getNameResolverRegistry() on hand-built Args and pass dependencies explicitly to your resolver constructor instead","Check for gRPC version skew: ensure the component constructing NameResolver.Args is on a version >= 1.74.0 that populates the registry field"],"exampleFix":"// before\nNameResolver.Args args = new NameResolver.Args.Builder()\n    .setUri(uri)\n    .build();\nNameResolverRegistry registry = args.getNameResolverRegistry(); // throws\n\n// after\nNameResolver.Args args = new NameResolver.Args.Builder()\n    .setUri(uri)\n    .setNameResolverRegistry(NameResolverRegistry.getDefaultRegistry())\n    .build();\nNameResolverRegistry registry = args.getNameResolverRegistry();","handlingStrategy":"validation","validationCode":"// before consuming Args\nNameResolverRegistry registry;\ntry {\n  registry = args.getNameResolverRegistry();\n} catch (IllegalStateException e) {\n  registry = NameResolverRegistry.getDefaultRegistry();\n}","typeGuard":"boolean hasRegistry(NameResolver.Args args) {\n  try { return args.getNameResolverRegistry() != null; }\n  catch (IllegalStateException e) { return false; }\n}","tryCatchPattern":"try {\n  registry = args.getNameResolverRegistry();\n} catch (IllegalStateException e) {\n  registry = NameResolverRegistry.getDefaultRegistry();\n}","preventionTips":["Set setNameResolverRegistry(NameResolverRegistry.getDefaultRegistry()) on any hand-built Args.Builder","Keep all gRPC artifacts on the same version so Args-producing code populates the 1.74.0+ field","Prefer taking resolver dependencies via constructor injection rather than reading optional Args fields"],"tags":["grpc","java","illegal-state","name-resolver","builder"],"backgroundTag":"missing-required-config-field","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"}