{"record":{"id":"e9b81eb177f835b4","repo":"TooTallNate/Java-WebSocket","slug":"1008","errorCode":"1008","errorMessage":"{message}","messagePattern":"\\{message\\}","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/java_websocket/extensions/permessage_deflate/PerMessageDeflateExtension.java","lineNumber":252,"sourceCode":"      // RFC 7692: If the \"agreed parameters\" contain the \"client|server_no_context_takeover\"\n      // extension parameter, the server|client MAY decompress each new message with an empty\n      // LZ77 sliding window.\n      if (isDecompressorResetAllowed) {\n        decompressor.reset();\n      }\n    }\n  }\n\n  private byte[] decompress(ByteBuffer buffer, boolean isFinal) throws InvalidDataException {\n    ByteArrayOutputStream decompressed = new ByteArrayOutputStream();\n    try {\n      decompress(buffer, decompressed);\n      // RFC 7692: Append empty deflate block to the tail end of the payload of the message\n      if (isFinal) {\n        decompress(ByteBuffer.wrap(EMPTY_DEFLATE_BLOCK), decompressed);\n      }\n    } catch (DataFormatException e) {\n      throw new InvalidDataException(CloseFrame.POLICY_VALIDATION, e.getMessage());\n    }\n    return decompressed.toByteArray();\n  }\n\n  private void decompress(ByteBuffer buffer, ByteArrayOutputStream decompressed)\n      throws DataFormatException {\n    if (buffer.hasArray()) {\n      decompressor.setInput(\n          buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());\n    } else {\n      byte[] input = new byte[buffer.remaining()];\n      buffer.duplicate().get(input);\n      decompressor.setInput(input);\n    }\n    byte[] chunk = new byte[TRANSFER_CHUNK_SIZE];\n    while (!decompressor.finished()) {\n      int length = decompressor.inflate(chunk);\n      if (length > 0) {","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/TooTallNate/Java-WebSocket/blob/afeacbf8c0f6f6a761c9d9daed8c813dd3b8ed7d/src/main/java/org/java_websocket/extensions/permessage_deflate/PerMessageDeflateExtension.java#L234-L270","documentation":"During decompression of a permessage-deflate message, the inflater throws DataFormatException because the payload is not valid DEFLATE data. The extension wraps it in an InvalidDataException with close code 1008 (POLICY_VALIDATION), carrying the inflater's message (e.g. 'invalid distance too far back'), and the connection is closed.","triggerScenarios":"decompress() is called (via decompressed()) and Inflater.inflate() throws DataFormatException — i.e. a frame payload claimed to be compressed (RSV1 set / negotiated permessage-deflate) is not valid zlib-deflate data or is missing the trailing 0x00 0x00 0xFF 0xFF empty block on the final fragment.","commonSituations":"Peers that claim permessage-deflate support but don't actually compress payloads; corruption by intermediaries/proxies; clients that forget the 4-byte tail block; double-decompression in custom code layered on the library.","solutions":["Verify both endpoints correctly implement RFC 7692, including appending the empty deflate block (0x00 0x00 0xFF 0xFF) to the last fragment before inflating.","Confirm the peer actually sends compressed payloads only when the permessage-deflate extension was negotiated; check the handshake's Sec-WebSocket-Extensions header.","Check for proxies/middleware that alter or truncate frame payloads.","Log the inflater's detail message (it's carried in the InvalidDataException) to pinpoint the deflate defect."],"exampleFix":"// before: client sends raw uncompressed text after negotiating permessage-deflate\nws.send(\"plain text\"); // peer's inflater fails\n\n// after: use the library's send API so frames are compressed as negotiated\nwebSocket.send(\"plain text\"); // library applies permessage-deflate correctly","handlingStrategy":"try-catch","validationCode":"// sanity-check the negotiated extensions before assuming compressed frames\nString ext = request.getHeader(\"Sec-WebSocket-Extensions\");\nboolean deflateNegotiated = ext != null && ext.contains(\"permessage-deflate\");","typeGuard":null,"tryCatchPattern":"try {\n    byte[] data = decompressed(frame);\n} catch (InvalidDataException e) {\n    // close code 1008, invalid deflate payload\n    logger.warn(\"deflate decode failed: {}\", e.getMessage());\n    webSocket.close(1008, \"invalid compressed payload\");\n}","preventionTips":["Ensure both ends implement RFC 7692 including the 0x00 0x00 0xFF 0xFF tail block","Don't bypass the library's frame encoding when compression is negotiated","Check proxies/intermediaries for payload mangling"],"tags":["websocket","permessage-deflate","decompression","rfc7692","policy-validation"],"backgroundTag":"invalid-json-response","analyzedSha":"afeacbf8c0f6f6a761c9d9daed8c813dd3b8ed7d","analyzedAt":"2026-09-09T14:39:47.546Z","contentChangedAt":"2026-09-09T14:39:47.546Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}