grpc/grpc-java · critical · GeneralSecurityException
Failed to get client TLS configuration from S2A.
Error message
Failed to get client TLS configuration from S2A.
What it means
SslContextFactory.createForClient() fetches the client TLS configuration from the S2A and wraps any IOException or InterruptedException from getClientTlsConfigurationFromS2A() in a GeneralSecurityException 'Failed to get client TLS configuration from S2A.'. The client cannot build its SslContext without this configuration, so the failure is fatal to client setup.
Source
Thrown at s2a/src/main/java/io/grpc/s2a/internal/handshaker/SslContextFactory.java:79
* @throws IOException if an unexpected response from S2A server is received.
* @throws InterruptedException if {@code stub} is closed.
*/
static SslContext createForClient(
S2AStub stub, String targetName, Optional<S2AIdentity> localIdentity)
throws IOException,
InterruptedException,
CertificateException,
KeyStoreException,
NoSuchAlgorithmException,
UnrecoverableKeyException,
GeneralSecurityException {
checkNotNull(stub, "stub should not be null.");
checkNotNull(targetName, "targetName should not be null on client side.");
GetTlsConfigurationResp.ClientTlsConfiguration clientTlsConfiguration;
try {
clientTlsConfiguration = getClientTlsConfigurationFromS2A(stub, localIdentity);
} catch (IOException | InterruptedException e) {
throw new GeneralSecurityException("Failed to get client TLS configuration from S2A.", e);
}
// Use the default value for timeout.
// Use the smallest possible value for cache size.
// The Provider is by default OPENSSL. No need to manually set it.
SslContextBuilder sslContextBuilder =
GrpcSslContexts.configure(SslContextBuilder.forClient())
.sessionCacheSize(1)
.sessionTimeout(0);
configureSslContextWithClientTlsConfiguration(clientTlsConfiguration, sslContextBuilder);
sslContextBuilder.trustManager(
S2ATrustManager.createForClient(stub, targetName, localIdentity));
sslContextBuilder.option(
OpenSslContextOption.PRIVATE_KEY_METHOD, S2APrivateKeyMethod.create(stub, localIdentity));
sslContextBuilder.option(
OpenSslContextOption.GROUPS,
new String[] {"X25519MLKEM768", "x25519", "secp256r1", "secp384r1", "secp521r1"});View on GitHub (pinned to 64daddc1f3)
Solutions
- Start/verify the S2A process and confirm the client's configured address reaches it.
- Create a fresh S2AStub before building the SslContext if a previous stub's stream closed.
- Retry createForClient() with backoff for transient connectivity issues during startup.
- Check the cause chain ( getTargetException/getCause ) to distinguish IOException from InterruptedException.
Example fix
// before SslContext ctx = SslContextFactory.createForClient(stub, targetName, identity); // fails if S2A down // after waitForS2aReady(channel, Duration.ofSeconds(10)); SslContext ctx = SslContextFactory.createForClient(stub, targetName, identity);
Defensive patterns
Strategy: try-catch
Validate before calling
// verify the S2A is ready before building the SslContext
if (!channel.awaitTerminationCheckOrReady(channel.getState(false), 10, TimeUnit.SECONDS)) {
throw new IllegalStateException("S2A channel not ready");
} Try / catch
try {
SslContext ctx = SslContextFactory.createForClient(stub, targetName, identity);
} catch (GeneralSecurityException e) {
// retry with a fresh stub for transient S2A availability issues
SslContext ctx = SslContextFactory.createForClient(newStubFor(channel), targetName, identity);
} Prevention
- Wait for S2A readiness before client bootstrap.
- Create a fresh stub for each SslContext build, or rebuild on failure.
- Retry with backoff during startup when the S2A may still be initializing.
- Check the wrapped cause to distinguish availability issues from interrupts.
When it happens
Trigger: Calling SslContextFactory.createForClient(stub, targetName, localIdentity) where the underlying S2AStub stream send/receive throws IOException or InterruptedException — S2A down, stream closed, or thread interrupted during configuration fetch.
Common situations: Client bootstrapping mTLS with S2A while the S2A process is not running; wrong S2A address in client config; reusing a closed stub; shutdown interrupting configuration retrieval.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Failed to send request to S2A.
- response from S2A server has ean error %d with error message
- TLS version %d is not supported.
- Signature Algorithm %d is not supported.
- Error occurred in response from S2A, error code: %d, error m
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/173394024ac1989d.
Report an issue: GitHub.