grpc/grpc-java · error · CertificateException
Error occurred in response from S2A, error code: %d, error m
Error message
Error occurred in response from S2A, error code: %d, error message: %s.
What it means
When the SessionResp from the S2A carries a non-zero status code, S2ATrustManager.checkPeerTrusted() throws a CertificateException formatted with the S2A-provided error code and message. This means the S2A itself reported an error processing the validation request, as opposed to a transport failure.
Source
Thrown at s2a/src/main/java/io/grpc/s2a/internal/handshaker/S2ATrustManager.java:160
}
SessionReq.Builder reqBuilder =
SessionReq.newBuilder().setValidatePeerCertificateChainReq(validatePeerCertificateChainReq);
if (localIdentity.isPresent()) {
reqBuilder.setLocalIdentity(localIdentity.get().getIdentity());
}
SessionResp resp;
try {
resp = stub.send(reqBuilder.build());
} catch (IOException e) {
throw new CertificateException("Failed to send request to S2A.", e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new CertificateException("Failed to send request to S2A.", e);
}
if (resp.hasStatus() && resp.getStatus().getCode() != 0) {
throw new CertificateException(
String.format(
"Error occurred in response from S2A, error code: %d, error message: %s.",
resp.getStatus().getCode(), resp.getStatus().getDetails()));
}
if (!resp.hasValidatePeerCertificateChainResp()) {
throw new CertificateException("No valid response received from S2A.");
}
ValidatePeerCertificateChainResp validationResult = resp.getValidatePeerCertificateChainResp();
if (validationResult.getValidationResult()
!= ValidatePeerCertificateChainResp.ValidationResult.SUCCESS) {
throw new CertificateException(validationResult.getValidationDetails());
}
}
private static ImmutableList<ByteString> certificateChainToDerChain(X509Certificate[] chain)
throws CertificateEncodingException {View on GitHub (pinned to 64daddc1f3)
Solutions
- Read the S2A error code/message in the exception and map it to the S2A-side issue.
- Verify the S2A is configured for the local identity and peer trust domains in use.
- Check client/S2A proto version compatibility and upgrade accordingly.
Example fix
// before
// ignore S2A status, unclear why validation fails
// after
catch (CertificateException e) {
logger.severe("S2A reported error: " + e.getMessage()); // inspect code + details
} Defensive patterns
Strategy: try-catch
Try / catch
try {
trustManager.checkServerTrusted(chain, authType);
} catch (CertificateException e) {
if (e.getMessage().startsWith("Error occurred in response from S2A")) {
// parse embedded S2A error code/details for diagnosis
logger.severe("S2A-side error: " + e.getMessage());
}
throw e;
} Prevention
- Keep client library and S2A binary versions compatible.
- Verify S2A configuration covers all local identities in use.
- Log the formatted error code/details for S2A-side triage.
When it happens
Trigger: checkClientTrusted/checkServerTrusted receives a SessionResp where resp.hasStatus() is true and resp.getStatus().getCode() != 0 — the S2A rejected or failed the request server-side.
Common situations: S2A not configured with the needed identity/key material; S2A internal error while validating the peer chain; version mismatch between client and S2A protobuf API.
Related errors
- Failed to send request to S2A.
- TLS version %d is not supported.
- Signature Algorithm %d is not supported.
- Error occurred in response from S2A, error code: %d, error m
- No valid response received from S2A.
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/02afe0bf331c77c9.
Report an issue: GitHub.