grpc/grpc-java · error · S2AConnectionException

Response from S2A server does NOT contain ClientTlsConfigura

Error message

Response from S2A server does NOT contain ClientTlsConfiguration.

What it means

This throw site in configureSslContextWithClientTlsConfiguration fires when the set of TLS protocol versions computed from the S2A server's min/max TLS version values is empty or unsupported, i.e. no usable TLS version can be negotiated for the client SSLContext. The line 156 region shows the empty-set guard right after buildTlsProtocolVersionSet().

Source

Thrown at s2a/src/main/java/io/grpc/s2a/internal/handshaker/SslContextFactory.java:156

    }
    return resp.getGetTlsConfigurationResp().getClientTlsConfiguration();
  }

  private static void configureSslContextWithClientTlsConfiguration(
      GetTlsConfigurationResp.ClientTlsConfiguration clientTlsConfiguration,
      SslContextBuilder sslContextBuilder)
      throws CertificateException,
          IOException,
          KeyStoreException,
          NoSuchAlgorithmException,
          UnrecoverableKeyException {
    sslContextBuilder.keyManager(createKeylessManager(clientTlsConfiguration));
    ImmutableSet<String> tlsVersions;
    tlsVersions =
        ProtoUtil.buildTlsProtocolVersionSet(
            clientTlsConfiguration.getMinTlsVersion(), clientTlsConfiguration.getMaxTlsVersion());
    if (tlsVersions.isEmpty()) {
      throw new S2AConnectionException(
          "Set of TLS versions received from S2A server is empty or not supported.");
    }
    sslContextBuilder.protocols(tlsVersions);
  }

  private static KeyManager createKeylessManager(
      GetTlsConfigurationResp.ClientTlsConfiguration clientTlsConfiguration)
      throws CertificateException,
          IOException,
          KeyStoreException,
          NoSuchAlgorithmException,
          UnrecoverableKeyException {
    X509Certificate[] certificates =
        new X509Certificate[clientTlsConfiguration.getCertificateChainCount()];
    for (int i = 0; i < clientTlsConfiguration.getCertificateChainCount(); ++i) {
      certificates[i] = convertStringToX509Cert(clientTlsConfiguration.getCertificateChain(i));
    }
    KeyManager[] keyManagers =

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Check the min/max TLS version values returned by the S2A server and confirm they are supported by your gRPC/netty-tcnative version
  2. Upgrade gRPC (and its TLS provider) so the S2A-reported TLS versions are recognized
  3. Fix S2A server configuration to advertise supported TLS versions (e.g. TLS 1.2/1.3)
  4. Ensure minTlsVersion is not greater than maxTlsVersion
Defensive patterns

Strategy: validation

Validate before calling

ClientTlsConfiguration cfg = resp.getGetTlsConfigurationResp().getClientTlsConfiguration();
Set<String> versions = ProtoUtil.buildTlsProtocolVersionSet(cfg.getMinTlsVersion(), cfg.getMaxTlsVersion());
if (versions.isEmpty()) {
  throw new IllegalStateException("S2A returned unsupported TLS versions: "
      + cfg.getMinTlsVersion() + ".." + cfg.getMaxTlsVersion());
}

Try / catch

try {
  SslContext ctx = SslContextFactory.createForClient();
} catch (S2AConnectionException e) {
  if (e.getMessage().contains("Set of TLS versions")) {
    // upgrade gRPC/TLS provider or reconfigure S2A server TLS versions
  }
}

Prevention

When it happens

Trigger: SslContextFactory.createForClient() receives a ClientTlsConfiguration whose ProtoUtil.buildTlsProtocolVersionSet(minTlsVersion, maxTlsVersion) yields an empty set (unknown/unsupported min or max TLS version enum, or min > max).

Common situations: S2A server and gRPC version disagree on supported TLS version enums (e.g. server reports a TLS version the bundled netty-tcnative/BoringSSL does not support), or a misconfigured min/max pair.

Related errors


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