{"record":{"id":"852e7f24b0826284","repo":"grpc/grpc-java","slug":"could-not-get-enough-key-data-from-the-handshake","errorCode":null,"errorMessage":"Could not get enough key data from the handshake.","messagePattern":"Could not get enough key data from the handshake\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"alts/src/main/java/io/grpc/alts/internal/AltsHandshakerClient.java","lineNumber":142,"sourceCode":"    return status;\n  }\n\n  /** Returns the result data of the handshake, if the handshake is completed. */\n  public HandshakerResult getResult() {\n    return result;\n  }\n\n  /**\n   * Returns the resulting key of the handshake, if the handshake is completed. Note that the key\n   * data returned from the handshake may be more than the key length required for the record\n   * protocol, thus we need to truncate to the right size.\n   */\n  public byte[] getKey() {\n    if (result == null) {\n      return null;\n    }\n    if (result.getKeyData().size() < KEY_LENGTH) {\n      throw new IllegalStateException(\"Could not get enough key data from the handshake.\");\n    }\n    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);","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerClient.java#L124-L160","documentation":"AltsHandshakerClient.getKey() extracts the session key from the handshake result's key data. If the handshake result has fewer than KEY_LENGTH bytes of key material, the handshake cannot supply a usable key and the method throws IllegalStateException instead of returning a short key.","triggerScenarios":"Calling getKey() after a handshake that completed with a truncated or missing key data field in the HandshakerResp from the ALTS handshaker service (result != null but result.getKeyData().size() < KEY_LENGTH).","commonSituations":"Incompatible ALTS handshaker service / client protocol versions where the response key length differs; a handshaker service bug or a partially-populated response being passed to the crypter constructor.","solutions":["Ensure the ALTS handshaker service (alts-handshaker) version is compatible with the grpc-alts client version","Re-run the handshake — a fresh negotiation usually returns complete key data","Check that the expected handshake protocol (e.g. ALTS_H2) is enabled on both peers so key material is exchanged","Catch IllegalStateException around crypter creation and fail the channel cleanly"],"exampleFix":"// before\nbyte[] key = client.getKey();\n// after\nif (client.getAliveState() && hasSufficientKeyData(client)) {\n  byte[] key = client.getKey();\n} else {\n  throw new IOException(\"ALTS handshake returned insufficient key material\");\n}","handlingStrategy":"try-catch","validationCode":"if (result == null || result.getKeyData().size() < KEY_LENGTH) {\n  throw new IOException(\"insufficient key material from ALTS handshake\");\n}","typeGuard":"null","tryCatchPattern":"try {\n  byte[] key = client.getKey();\n} catch (IllegalStateException e) {\n  restartHandshake(); // re-negotiate to obtain complete key data\n}","preventionTips":["Keep handshaker service and grpc-alts versions aligned","Ensure the expected handshake protocol is enabled on both peers","Re-run the handshake instead of using partial key data"],"tags":["grpc","alts","handshake","crypto","keys"],"backgroundTag":"handshake-key-material-short","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"}