Skip to content

Snappy gRPC response fails Java client decompression: "Not a framed Snappy stream" #2599

@jojoxhsieh

Description

@jojoxhsieh

Bug Report

Version

From our project:

  • tonic = 0.14.5

Platform

macOS (Darwin 25.4.0), arm64

Crates

  • tonic

Description

We see a Snappy interoperability failure specifically when the gRPC response payload is empty (0-byte protobuf payload), e.g. IngestFeaturesResponse::default().
I tried this code:

use tonic::codec::CompressionEncoding;
// server setup
let svc = ServingServiceV2Server::new(service_impl)
    .send_compressed(CompressionEncoding::Gzip)
    .send_compressed(CompressionEncoding::Snappy)
    .accept_compressed(CompressionEncoding::Gzip)
    .accept_compressed(CompressionEncoding::Snappy);
// handler returns empty/default response
async fn ingest_features(...) -> Result<Response<IngestFeaturesResponse>, Status> {
    Ok(Response::new(IngestFeaturesResponse::default()))
}

(Java client accepts/computes gRPC compression and has Snappy decompressor enabled.)

I expected to see this happen:
When response compression is snappy, client should still decode successfully even if protobuf payload length is 0.

Instead, this happened:
Java client fails during decompression/deframing with:
io.grpc.StatusRuntimeException: UNKNOWN
Caused by: java.lang.RuntimeException: java.io.IOException: Not a framed Snappy stream
at io.grpc.internal.MessageDeframer.getCompressedBody(...)
Caused by: java.io.IOException: Not a framed Snappy stream
at org.apache.commons.compress.compressors.snappy.FramedSnappyCompressorInputStream.readStreamIdentifier(...)

Additional observations:
Forcing gzip avoids the issue.
Failure appears at compression/decompression layer, not protobuf business parsing.
The issue appears correlated with empty response payloads under Snappy.

Question: Is empty-message handling under Snappy expected to emit framed snappy bytes in this case, or should compression be skipped automatically for 0-byte messages?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions