grpc/grpc-java · error · IllegalArgumentException

Unexpected error converting ServerCredentials to Netty SslCo

Error message

Unexpected error converting ServerCredentials to Netty SslContext

What it means

ProtocolNegotiators.from(ServerCredentials) converts TlsServerCredentials into a Netty SslContext. If SslContext builder.build() throws SSLException, it is rethrown as IllegalArgumentException with message "Unexpected error converting ServerCredentials to Netty SslContext" and the SSLException as cause. This surfaces TLS material problems at server-builder time.

Source

Thrown at netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java:232

          break;

        case REQUIRE:
          builder.clientAuth(io.netty.handler.ssl.ClientAuth.REQUIRE);
          break;

        case NONE:
          builder.clientAuth(io.netty.handler.ssl.ClientAuth.NONE);
          break;

        default:
          return FromServerCredentialsResult.error(
              "Unknown TlsServerCredentials.ClientAuth value: " + tlsCreds.getClientAuth());
      }
      SslContext sslContext;
      try {
        sslContext = builder.build();
      } catch (SSLException ex) {
        throw new IllegalArgumentException(
            "Unexpected error converting ServerCredentials to Netty SslContext", ex);
      }
      return FromServerCredentialsResult.negotiator(serverTlsFactory(sslContext));

    } else if (creds instanceof InsecureServerCredentials) {
      return FromServerCredentialsResult.negotiator(serverPlaintextFactory());

    } else if (creds instanceof NettyServerCredentials) {
      NettyServerCredentials nettyCreds = (NettyServerCredentials) creds;
      return FromServerCredentialsResult.negotiator(nettyCreds.getNegotiator());

    } else if (creds instanceof ChoiceServerCredentials) {
      ChoiceServerCredentials choiceCreds = (ChoiceServerCredentials) creds;
      StringBuilder error = new StringBuilder();
      for (ServerCredentials innerCreds : choiceCreds.getCredentialsList()) {
        FromServerCredentialsResult result = from(innerCreds);
        if (result.error == null) {
          return result;

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Inspect the cause SSLException for the concrete TLS parsing failure.
  2. Verify the private key and certificate chain match and are in a supported format (unencrypted PEM/PKCS#8).
  3. Add or align netty-tcnative-boringssl-static (or Conscrypt) with your netty version, or force the JDK SslProvider.
  4. Test the material locally: GrpcSslContexts.forServer(cert, key).build() in isolation to reproduce the failure.

Example fix

// before
TlsServerCredentials creds = TlsServerCredentials.newBuilder()
    .keyManager(badCert, encryptedKey) // parse fails later as IAE
    .build();
// after
TlsServerCredentials creds = TlsServerCredentials.newBuilder()
    .keyManager(certX509, unencryptedPrivateKey) // validated PEM pair
    .build();
Defensive patterns

Strategy: try-catch

Validate before calling

try {
  GrpcSslContexts.forServer(certFile, keyFile).build(); // pre-validate TlsServerCredentials material
} catch (SSLException e) {
  throw new IllegalArgumentException("Bad TLS material: " + e.getMessage(), e);
}

Try / catch

try {
  Server s = NettyServerBuilder.forAddress(addr, tlsCreds).build();
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("converting ServerCredentials")) {
    // cause SSLException: fix key/cert material or SslProvider
  }
}

Prevention

When it happens

Trigger: Calling NettyServerBuilder.forAddress(addr, tlsServerCredentials) (or forPort) where the TlsServerCredentials' key/cert managers cannot be turned into a valid SslContext: malformed key or certificate data, unsupported key format, or incompatible TLS provider configuration.

Common situations: TlsServerCredentials built with a bad private key or mismatched cert chain; keys in unsupported formats (e.g. encrypted PKCS#8 without a password supplier); missing/mismatched netty-tcnative so the default SslProvider fails; Conscrypt/JDK provider conflicts.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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