grpc/grpc-java · error · IllegalArgumentException

${jdkProvider} selected, but Java 9+ and Jetty NPN/ALPN unav

Error message

${jdkProvider} selected, but Java 9+ and Jetty NPN/ALPN unavailable

What it means

When a Conscrypt provider is selected at the JDK level, gRPC still needs an ALPN application-protocol mechanism. If Jetty NPN is not configured and Java 9+ ALPN is unavailable (i.e. Java 8 without the Jetty ALPN agent), this IllegalArgumentException is thrown.

Source

Thrown at netty/src/main/java/io/grpc/netty/GrpcSslContexts.java:209

  /**
   * Set ciphers and APN appropriate for gRPC. Precisely what is set is permitted to change, so if
   * an application requires particular settings it should override the options set here. For
   * client builders, HTTPS endpoint identification is enabled by default.
   */
  @CanIgnoreReturnValue
  public static SslContextBuilder configure(SslContextBuilder builder, Provider jdkProvider) {
    ApplicationProtocolConfig apc;
    if (SUN_PROVIDER_NAME.equals(jdkProvider.getName())) {
      // Jetty ALPN/NPN only supports one of NPN or ALPN
      if (JettyTlsUtil.isJettyAlpnConfigured()) {
        apc = ALPN;
      } else if (JettyTlsUtil.isJettyNpnConfigured()) {
        apc = NPN;
      } else if (JettyTlsUtil.isJava9AlpnAvailable()) {
        apc = ALPN;
      } else {
        throw new IllegalArgumentException(
            jdkProvider.getName() + " selected, but Java 9+ and Jetty NPN/ALPN unavailable");
      }
    } else if (IBM_PROVIDER_NAME.equals(jdkProvider.getName())
        || OPENJSSE_PROVIDER_NAME.equals(jdkProvider.getName())
        || BCJSSE_PROVIDER_NAME.equals(jdkProvider.getName())) {
      if (JettyTlsUtil.isJava9AlpnAvailable()) {
        apc = ALPN;
      } else {
        throw new IllegalArgumentException(
            jdkProvider.getName() + " selected, but Java 9+ ALPN unavailable");
      }
    } else if (ConscryptLoader.isConscrypt(jdkProvider)) {
      apc = ALPN;
      // TODO: Conscrypt triggers failures in the TrustManager.
      // https://github.com/grpc/grpc-java/issues/7765
      builder.protocols("TLSv1.2");
    } else {
      throw new IllegalArgumentException("Unknown provider; can't configure: " + jdkProvider);

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Upgrade to Java 9+ where ALPN is built in
  2. On Java 8, add the Jetty ALPN boot jar (-Xbootclasspath) matching the JDK version
  3. Use SslProvider.OPENSSL with netty-tcnative, which handles ALPN itself

Example fix

// before (Java 8, no ALPN agent)
java -jar app.jar
// after
java -Xbootclasspath/p:alpn-boot-8u252.jar -jar app.jar
Defensive patterns

Strategy: validation

Validate before calling

if (Conscrypt.isAvailable() && !JettyTlsUtil.isJettyNpnConfigured() && !JettyTlsUtil.isJava9AlpnAvailable()) { /* need Jetty ALPN agent or Java 9+ */ }

Type guard

boolean conscryptUsable() { return JettyTlsUtil.isJettyNpnConfigured() || JettyTlsUtil.isJava9AlpnAvailable(); }

Try / catch

try { GrpcSslContexts.configure(b, SslProvider.JDK); } catch (IllegalArgumentException e) { throw new IllegalStateException("Add Jetty ALPN boot jar or upgrade to Java 9+", e); }

Prevention

When it happens

Trigger: configure(builder, jdkProvider) where jdkProvider is Conscrypt (not via the JDK_PROVIDER default path that allows Conscrypt workaround) and neither Jetty NPN nor Java 9 ALPN is available.

Common situations: Conscrypt registered as a security provider on Java 8 without the Jetty ALPN boot agent; containers on old JREs; explicitly selecting the Conscrypt JDK provider for TLS while lacking ALPN support.

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/33d77241754e10b0. Report an issue: GitHub.