{"record":{"id":"bb56649b27de7de8","repo":"grpc/grpc-java","slug":"invalid-frame-length-datalength","errorCode":null,"errorMessage":"Invalid frame length ${dataLength}","messagePattern":"Invalid frame length (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"alts/src/main/java/io/grpc/alts/internal/AltsFraming.java","lineNumber":287,"sourceCode":"\n      if (isComplete) {\n        return true;\n      }\n\n      // Read enough bytes to determine the length\n      while (buffer.position() < FRAME_LENGTH_HEADER_SIZE && input.hasRemaining()) {\n        buffer.put(input.get());\n      }\n\n      // If we have enough bytes to determine the length, read the length and ensure that our\n      // internal buffer is large enough.\n      if (buffer.position() == FRAME_LENGTH_HEADER_SIZE && input.hasRemaining()) {\n        ByteBuffer bufferAlias = buffer.duplicate();\n        ((Buffer) bufferAlias).flip();\n        bufferAlias.order(ByteOrder.LITTLE_ENDIAN);\n        int dataLength = bufferAlias.getInt();\n        if (dataLength < FRAME_MESSAGE_TYPE_HEADER_SIZE || dataLength > MAX_DATA_LENGTH) {\n          throw new IllegalArgumentException(\"Invalid frame length \" + dataLength);\n        }\n        // Maybe resize the buffer\n        int frameLength = dataLength + FRAME_LENGTH_HEADER_SIZE;\n        if (buffer.capacity() < frameLength) {\n          buffer = ByteBuffer.allocate(frameLength);\n          buffer.order(ByteOrder.LITTLE_ENDIAN);\n          buffer.putInt(dataLength);\n        }\n        ((Buffer) buffer).limit(frameLength);\n      }\n\n      // TODO: Similarly extract and check message type.\n\n      // Read the remaining data into the internal buffer.\n      copy(buffer, input);\n      if (!buffer.hasRemaining()) {\n        ((Buffer) buffer).flip();\n        isComplete = true;","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/alts/src/main/java/io/grpc/alts/internal/AltsFraming.java#L269-L305","documentation":"AltsFraming's parser reads a little-endian 4-byte frame length header and validates it: the declared data length must be at least FRAME_MESSAGE_TYPE_HEADER_SIZE and at most MAX_DATA_LENGTH. A length outside that range means the byte stream is corrupt or not an ALTS frame, so parsing fails fast with IllegalArgumentException.","triggerScenarios":"Feeding the ALTS frame parser bytes whose 4-byte length prefix decodes below the message-type header size (including 0/negative) or above MAX_DATA_LENGTH — i.e. desynchronized stream, corrupted framing, or wrong protocol bytes fed to the parser.","commonSituations":"Handshaker/transport byte-stream corruption, an off-by-N misalignment while copying frame bytes, or piping a non-ALTS stream into the ALTS frame parser in unit tests.","solutions":["Verify the peer is speaking the same ALTS framing protocol version","Check the code producing/consuming the stream for byte misalignment (e.g. incorrect slice/offset of the length header)","If dataLength is 0 confirm the writer always includes the message-type header, not just the payload","Reset the connection — once the frame stream is desynchronized it cannot be recovered"],"exampleFix":"// writer side: before\nbuf.putInt(payload.length);\n// after — include message type + payload in the length field\nint dataLength = FRAME_MESSAGE_TYPE_HEADER_SIZE + payload.length;\nbuf.putInt(dataLength);","handlingStrategy":"try-catch","validationCode":"int len = readLittleEndianInt32(header);\nif (len < FRAME_MESSAGE_TYPE_HEADER_SIZE || len > MAX_DATA_LENGTH) {\n  throw new IOException(\"corrupt ALTS frame length: \" + len);\n}","typeGuard":"null","tryCatchPattern":"try {\n  parser.readBytes(input);\n} catch (IllegalArgumentException e) {\n  // framing desynchronized: discard the stream and reset the connection\n  connection.reset();\n}","preventionTips":["Ensure the length field includes the message-type header","Never re-slice frame buffers without the 4-byte header offset","Don't feed non-ALTS byte streams into the ALTS parser"],"tags":["grpc","alts","framing","protocol","corruption"],"backgroundTag":"invalid-argument-format","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"}