{"record":{"id":"08429b45c30792a0","repo":"grpc/grpc-java","slug":"handshaker-service-error-status-getdetails","errorCode":null,"errorMessage":"Handshaker service error: ${status.getDetails()}","messagePattern":"Handshaker service error: (.+?)","errorType":"exception","errorClass":"GeneralSecurityException","httpStatus":null,"severity":"error","filePath":"alts/src/main/java/io/grpc/alts/internal/AltsHandshakerClient.java","lineNumber":162,"sourceCode":"    byte[] key = new byte[KEY_LENGTH];\n    result.getKeyData().substring(0, KEY_LENGTH).copyTo(key, 0);\n    return key;\n  }\n\n  /**\n   * Parses a handshake response, setting the status, result, and closing the handshaker, as needed.\n   */\n  private void handleResponse(HandshakerResp resp) throws GeneralSecurityException {\n    status = resp.getStatus();\n    if (resp.hasResult()) {\n      result = resp.getResult();\n      close();\n    }\n    if (status.getCode() != Status.Code.OK.value()) {\n      String error = \"Handshaker service error: \" + status.getDetails();\n      logger.log(ChannelLogLevel.DEBUG, error);\n      close();\n      throw new GeneralSecurityException(error);\n    }\n  }\n\n  /**\n   * Starts a client handshake. A GeneralSecurityException is thrown if the handshaker service is\n   * interrupted or fails. Note that isFinished() must be false before this function is called.\n   *\n   * @return the frame to give to the peer.\n   * @throws GeneralSecurityException or IllegalStateException\n   */\n  public ByteBuffer startClientHandshake() throws GeneralSecurityException {\n    Preconditions.checkState(!isFinished(), \"Handshake has already finished.\");\n    HandshakerReq.Builder req = HandshakerReq.newBuilder();\n    setStartClientFields(req);\n    HandshakerResp resp;\n    try {\n      logger.log(ChannelLogLevel.DEBUG, \"Send ALTS handshake request to upstream\");\n      resp = handshakerStub.send(req.build());","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerClient.java#L144-L180","documentation":"AltsHandshakerClient.handleResponse() checks the status code embedded in each HandshakerResp returned by the ALTS handshaker service. Any non-OK status (e.g. INTERNAL, INVALID_ARGUMENT, UNAUTHENTICATED) aborts the handshake: the client logs the details, closes the stream, and throws GeneralSecurityException carrying the service's details string.","triggerScenarios":"The remote ALTS handshaker service returns a non-OK status in a response during startClientHandshake, startServerHandshake, or next() — e.g. peer identity rejected, unsupported handshake protocol, or service-side failure.","commonSituations":"Mismatched peer service accounts / IAM roles for ALTS on GCP, unsupported ALTS protocol negotiated, handshaker service outage, or wrong handshaker service address configured.","solutions":["Read status.getDetails() in the exception message — it names the service-side reason; fix the underlying identity/protocol problem","Verify both peers run in an environment supporting ALTS (e.g. correct GCP service accounts and Compute Engine metadata)","Confirm the handshaker service address/port is correct and the service is healthy","Retry the connection; transient handshaker service errors often resolve on a new handshake"],"exampleFix":"// before\nAltsChannelBuilder.forTarget(target).handshakerAddress(badAddr).build();\n// after\nAltsChannelBuilder.forTarget(target)\n    .handshakerAddress(\"metadata.google.internal:8080\")\n    .build(); // and retry on GeneralSecurityException","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  client.startClientHandshake(next);\n} catch (GeneralSecurityException e) {\n  logger.warn(\"ALTS handshake failed: \" + e.getMessage()); // includes status details\n  scheduleReconnectWithBackoff();\n}","preventionTips":["Log and inspect status details — they identify IAM/identity or protocol problems","Validate GCP service accounts and ALTS environment before deploying","Add exponential backoff retry for transient handshaker service errors"],"tags":["grpc","alts","handshake","handshaker-service","gcp"],"backgroundTag":"handshaker-service-error","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}