{"record":{"id":"579698e1642046cc","repo":"grpc/grpc-java","slug":"unsupported-compression-method","errorCode":null,"errorMessage":"Unsupported compression method","messagePattern":"Unsupported compression method","errorType":"exception","errorClass":"ZipException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/grpc/internal/GzipInflatingBuffer.java","lineNumber":326,"sourceCode":"      }\n    }\n    // If we finished a gzip block, check if we have enough bytes to read another header\n    isStalled =\n        !madeProgress\n            || (state == State.HEADER && gzipMetadataReader.readableBytes() < GZIP_HEADER_MIN_SIZE);\n\n    return bytesRead;\n  }\n\n  private boolean processHeader() throws ZipException {\n    if (gzipMetadataReader.readableBytes() < GZIP_HEADER_MIN_SIZE) {\n      return false;\n    }\n    if (gzipMetadataReader.readUnsignedShort() != GZIP_MAGIC) {\n      throw new ZipException(\"Not in GZIP format\");\n    }\n    if (gzipMetadataReader.readUnsignedByte() != 8) {\n      throw new ZipException(\"Unsupported compression method\");\n    }\n    gzipHeaderFlag = gzipMetadataReader.readUnsignedByte();\n    gzipMetadataReader.skipBytes(6 /* remaining header bytes */);\n    state = State.HEADER_EXTRA_LEN;\n    return true;\n  }\n\n  private boolean processHeaderExtraLen() {\n    if ((gzipHeaderFlag & HEADER_EXTRA_FLAG) != HEADER_EXTRA_FLAG) {\n      state = State.HEADER_NAME;\n      return true;\n    }\n    if (gzipMetadataReader.readableBytes() < UNSIGNED_SHORT_SIZE) {\n      return false;\n    }\n    headerExtraToRead = gzipMetadataReader.readUnsignedShort();\n    state = State.HEADER_EXTRA;\n    return true;","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/core/src/main/java/io/grpc/internal/GzipInflatingBuffer.java#L308-L344","documentation":"GzipInflatingBuffer decompresses gzip-wrapped gRPC message streams. During header parsing (processHeader), after verifying the GZIP magic number, it checks that the compression method byte equals 8 (the only method defined by RFC 1952, 'deflate'). Any other byte means the stream is not standard gzip, so a ZipException('Unsupported compression method') is thrown.","triggerScenarios":"A compressed gRPC message stream's first bytes decode to a valid GZIP magic (0x1f 0x8b) but the third byte (compression method) is not 8 — e.g. the payload was produced by a different compression scheme or is otherwise corrupted/truncated in the header.","commonSituations":"Client and server disagree on compression; a proxy or intermediary mangles/replaces the compressed body; a custom marshaller writes raw deflate or zstd bytes mislabeled as gzip; truncated or bit-flipped data from a broken connection.","solutions":["Verify the sender actually produces gzip (method byte 8) — dump the first bytes of the payload and confirm 1f 8b 08","Align the gRPC compression registry on both peers (use the same encoding, e.g. gzip on both sides)","Remove/fix proxies that rewrite or corrupt response bodies","Capture the stream and validate it with `gzip -t` to rule out corruption upstream"],"exampleFix":"// before: sending raw deflate bytes with gzip Content-Encoding\nDeflater deflater = new Deflater();\nbyte[] body = compress(deflater, data);\n// after: use a real GZIPOutputStream so the header declares method 8\nByteArrayOutputStream bos = new ByteArrayOutputStream();\ntry (GZIPOutputStream gz = new GZIPOutputStream(bos)) {\n  gz.write(data);\n}\nbyte[] body = bos.toByteArray();","handlingStrategy":"validation","validationCode":"// validate gzip payload before sending\nif (payload.length < 3 || payload[0] != 0x1f || payload[1] != (byte)0x8b) throw new IllegalArgumentException(\"not gzip\");\nif ((payload[2] & 0xff) != 8) throw new IllegalArgumentException(\"compression method must be 8 (deflate)\");","typeGuard":"static boolean isGzipDeflate(byte[] b) {\n  return b != null && b.length >= 3 && b[0] == 0x1f && b[1] == (byte)0x8b && (b[2] & 0xff) == 8;\n}","tryCatchPattern":"try { call(...); } catch (StatusRuntimeException e) {\n  if (e.getCause() instanceof ZipException && e.getCause().getMessage().contains(\"Unsupported compression method\")) {\n    // renegotiate compression or fall back to identity encoding\n  } else throw e;\n}","preventionTips":["Use GZIPOutputStream or the gRPC gzip compressor, never hand-rolled gzip headers","Register the same compression codecs on client and server","Interrogate suspicious payloads with `gzip -t` before deploying"],"tags":["grpc","gzip","compression","data-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"}