grpc/grpc-java · error · S2AConnectionException

response from S2A server has ean error %d with error message

Error message

response from S2A server has ean error %d with error message %s.

What it means

S2AConnectionException thrown by getClientTlsConfigurationFromS2A when the S2A (Service-to-Agent) server's GetTlsConfiguration response carries a non-zero status code. The S2A server failed to produce a client-side TLS configuration, so gRPC cannot build the client SSLContext. The status code and server-provided details are embedded in the message.

Source

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

    SessionReq.Builder reqBuilder = SessionReq.newBuilder();
    if (localIdentity.isPresent()) {
      reqBuilder.setLocalIdentity(localIdentity.get().getIdentity());
    }
    Optional<AuthenticationMechanism> authMechanism =
        GetAuthenticationMechanisms.getAuthMechanism(localIdentity,
        GetAuthenticationMechanisms.TOKEN_MANAGER);
    if (authMechanism.isPresent()) {
      reqBuilder.addAuthenticationMechanisms(authMechanism.get());
    }
    SessionResp resp =
        stub.send(
            reqBuilder
                .setGetTlsConfigurationReq(
                    GetTlsConfigurationReq.newBuilder()
                        .setConnectionSide(ConnectionSide.CONNECTION_SIDE_CLIENT))
                .build());
    if (resp.hasStatus() && resp.getStatus().getCode() != 0) {
      throw new S2AConnectionException(
          String.format(
              "response from S2A server has ean error %d with error message %s.",
              resp.getStatus().getCode(), resp.getStatus().getDetails()));
    }
    if (!resp.getGetTlsConfigurationResp().hasClientTlsConfiguration()) {
      throw new S2AConnectionException(
          "Response from S2A server does NOT contain ClientTlsConfiguration.");
    }
    return resp.getGetTlsConfigurationResp().getClientTlsConfiguration();
  }

  private static void configureSslContextWithClientTlsConfiguration(
      GetTlsConfigurationResp.ClientTlsConfiguration clientTlsConfiguration,
      SslContextBuilder sslContextBuilder)
      throws CertificateException,
          IOException,
          KeyStoreException,
          NoSuchAlgorithmException,

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Read the %d code and %s details in the message to identify the server-side failure cause
  2. Check S2A server logs for the corresponding request failure
  3. Verify the S2A server is healthy and has access to the required TLS material/identity
  4. Confirm network connectivity and correct S2A target address configuration
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify S2A reachability before building the context
S2AStub stub = /* ... */;
GetTlsConfigurationResp resp = stub.getTlsConfiguration(/* client req */);
if (resp.hasStatus() && resp.getStatus().getCode() != 0) {
  throw new IllegalStateException("S2A unhealthy: " + resp.getStatus().getDetails());
}

Try / catch

try {
  SslContext ctx = SslContextFactory.createForClient();
} catch (S2AConnectionException e) {
  logger.atSevere().withCause(e).log("S2A returned error status; check S2A server health");
  // fall back to locally-configured TLS or fail fast
}

Prevention

When it happens

Trigger: Calling SslContextFactory.createForClient() when the S2A server responds to a CONNECTION_SIDE_CLIENT GetTlsConfigurationReq with resp.getStatus().getCode() != 0.

Common situations: S2A server misconfiguration, the S2A service cannot access the requested identity/credentials, or the S2A backend is degraded/unhealthy during mTLS handshakes.

Related errors


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