{"record":{"id":"810a1e2838666c35","repo":"grpc/grpc-java","slug":"jndi-is-not-currently-available","errorCode":null,"errorMessage":"JNDI is not currently available","messagePattern":"JNDI is not currently available","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/grpc/internal/JndiResourceResolverFactory.java","lineNumber":266,"sourceCode":"        namingEnumeration.close();\n      } catch (NamingException ignored) {\n        // ignore\n      }\n      throw e;\n    }\n\n    private static void closeThenThrow(DirContext ctx, NamingException e) throws NamingException {\n      try {\n        ctx.close();\n      } catch (NamingException ignored) {\n        // ignore\n      }\n      throw e;\n    }\n\n    private static void checkAvailable() {\n      if (JNDI_UNAVAILABILITY_CAUSE != null) {\n        throw new UnsupportedOperationException(\n            \"JNDI is not currently available\", JNDI_UNAVAILABILITY_CAUSE);\n      }\n    }\n  }\n}\n","sourceCodeStart":248,"sourceCodeEnd":272,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/core/src/main/java/io/grpc/internal/JndiResourceResolverFactory.java#L248-L272","documentation":"JndiResourceResolverFactory resolves DNS SRV/TXT records for gRPC name resolution via JNDI. At construction it probes JNDI availability and caches a cause if unavailable; checkAvailable() rethrows UnsupportedOperationException('JNDI is not currently available') whenever resolution is attempted on such a runtime.","triggerScenarios":"Calling gRPC name resolution that requires the 'dns' resolver with JNDI-based SRV lookup on a JVM lacking javax.naming (jre lacking JNDI/DNS provider) or where the initial DirContext cannot be created (JNDI_UNAVAILABILITY_CAUSE non-null).","commonSituations":"Running on a trimmed JRE (e.g. custom jlink image) without java.naming module; android or minimal container images; missing dnsns/jndi provider jars on older Java 8 builds.","solutions":["Run on a full JDK/JRE that includes JNDI and the DNS provider (add java.naming module on jlink images: --add-modules java.naming)","Add the dependency providing com.sun.jndi.dns.DnsContextFactory (or upgrade to a JRE that bundles it)","Use gRPC's non-JNDI DNS resolver path (io.grpc:grpc-services dns, or set -Dio.grpc.internal.DnsNameResolverProvider.enableJndi=false so the fallback resolver is used)","Check the cause attached to the UnsupportedOperationException — it names exactly why JNDI was deemed unavailable"],"exampleFix":"// before: jlink image without JNDI\njlink --add-modules java.base --output image\n// after\njlink --add-modules java.base,java.naming --output image","handlingStrategy":"fallback","validationCode":"// probe JNDI availability before choosing the resolver\nboolean jndi;\ntry { Class.forName(\"javax.naming.directory.InitialDirContext\"); jndi = true; }\nclass NotFound extends RuntimeException {}\ncatch (ClassNotFoundException e) { jndi = false; }","typeGuard":null,"tryCatchPattern":"try {\n  resolver.getAllRecords(\"\", \"_grpc_config.example.com\");\n} catch (UnsupportedOperationException e) {\n  if (\"JNDI is not currently available\".equals(e.getMessage())) {\n    resolver = fallbackDnsResolver; // A-record-only resolver\n  } else throw e;\n}","preventionTips":["Include java.naming in jlink images (--add-modules java.naming)","Read the attached cause — it pinpoints the missing JNDI piece","Prefer the non-JNDI DNS resolver where SRV records are not required"],"tags":["grpc","jndi","dns","runtime-environment"],"backgroundTag":"missing-optional-dependency","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}