grpc/grpc-java · error · IllegalArgumentException

Unknown provider; can't configure: ${jdkProvider}

Error message

Unknown provider; can't configure: ${jdkProvider}

What it means

After checking known JDK TLS providers (Conscrypt, IBM, OpenJSSE, BCJSSE, default SunJSSE paths), any unrecognized provider name falls through to this IllegalArgumentException because gRPC cannot determine a safe ALPN configuration for it.

Source

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

        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);
    }
    return builder
        .sslProvider(SslProvider.JDK)
        .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
        .applicationProtocolConfig(apc)
        .sslContextProvider(jdkProvider)
        .endpointIdentificationAlgorithm(DEFAULT_ENDPOINT_IDENTIFICATION_ALGORITHM);
  }

  /**
   * Returns OpenSSL if available, otherwise returns the JDK provider.
   */
  private static SslProvider defaultSslProvider() {
    if (OpenSsl.isAvailable()) {
      logger.log(Level.FINE, "Selecting OPENSSL");
      return SslProvider.OPENSSL;
    }
    Provider provider = findJdkProvider();

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Use a supported provider: Conscrypt, the platform default (SunJSSE), or netty-tcnative
  2. Call the no-arg configure(builder) overload and let gRPC choose the provider
  3. Use SslProvider.OPENSSL to bypass JDK provider detection entirely

Example fix

// before
Provider custom = new MyCustomJsseProvider();
GrpcSslContexts.configure(builder, custom);
// after
GrpcSslContexts.configure(builder); // auto-selects a supported provider
Defensive patterns

Strategy: try-catch

Validate before calling

String name = jdkProvider.getName(); boolean known = name.equals("SunJSSE") || name.contains("Conscrypt") || name.equals("IBMJSSE2") || name.equals("OpenJSSE") || name.equals("BCJSSE");

Type guard

boolean isKnownProvider(Provider p) { return ConscryptLoader.isConscrypt(p) || p.getClass().getName().startsWith("com.sun.net.ssl"); }

Try / catch

try { return GrpcSslContexts.configure(b, jdkProvider); } catch (IllegalArgumentException e) { return GrpcSslContexts.configure(b, SslProvider.OPENSSL); }

Prevention

When it happens

Trigger: configure(builder, jdkProvider) receiving a JDK SSLContext.TLS provider whose name matches none of the known cases (e.g. a custom or third-party JSSE provider).

Common situations: Registering a custom JSSE implementation; unusual vendor JDKs; a provider whose getName() differs from expected constants after vendor rename.

Related errors


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