grpc/grpc-java · error · UnsupportedOperationException

JNDI is not currently available

Error message

JNDI is not currently available

What it means

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.

Solutions

  1. Run on a full JDK/JRE that includes JNDI and the DNS provider (add java.naming module on jlink images: --add-modules java.naming)
  2. Add the dependency providing com.sun.jndi.dns.DnsContextFactory (or upgrade to a JRE that bundles it)
  3. 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)
  4. Check the cause attached to the UnsupportedOperationException — it names exactly why JNDI was deemed unavailable

Example fix

// before: jlink image without JNDI
jlink --add-modules java.base --output image
// after
jlink --add-modules java.base,java.naming --output image
Defensive patterns

Strategy: fallback

Validate before calling

// probe JNDI availability before choosing the resolver
boolean jndi;
try { Class.forName("javax.naming.directory.InitialDirContext"); jndi = true; }
class NotFound extends RuntimeException {}
catch (ClassNotFoundException e) { jndi = false; }

Try / catch

try {
  resolver.getAllRecords("", "_grpc_config.example.com");
} catch (UnsupportedOperationException e) {
  if ("JNDI is not currently available".equals(e.getMessage())) {
    resolver = fallbackDnsResolver; // A-record-only resolver
  } else throw e;
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/810a1e2838666c35. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/io/grpc/internal/JndiResourceResolverFactory.java:266

        namingEnumeration.close();
      } catch (NamingException ignored) {
        // ignore
      }
      throw e;
    }

    private static void closeThenThrow(DirContext ctx, NamingException e) throws NamingException {
      try {
        ctx.close();
      } catch (NamingException ignored) {
        // ignore
      }
      throw e;
    }

    private static void checkAvailable() {
      if (JNDI_UNAVAILABILITY_CAUSE != null) {
        throw new UnsupportedOperationException(
            "JNDI is not currently available", JNDI_UNAVAILABILITY_CAUSE);
      }
    }
  }
}

View on GitHub (pinned to 64daddc1f3)