Skip to content

[Triple][3.3.6] First client-streaming call after consumer restart may fail with malformed gRPC frame and IllegalReferenceCountException #16414

Description

@1536191986zh-cloud

Pre-check

  • I am sure that all the content I provide is in English.

Search before asking

  • I had searched in the issues and found no similar issues.

Apache Dubbo Component

Java SDK (apache/dubbo)

Dubbo Version

Apache Dubbo:3.3.6
JDK:17

Steps to reproduce this issue

  1. Start a Triple provider in one JVM with a client-streaming RPC:
    rpc Upload(stream UploadFrame) returns (UploadResult);

  2. Start a new consumer JVM and immediately invoke Upload:
    send the metadata frame first, then send one or more file-content frames.

  3. The first call after the consumer restart may fail. Subsequent calls usually succeed without restarting either side.

  4. The issue is reproducible with both:

    • a single Dubbo port with ext-protocol: tri
    • native tri protocol
  5. The payload can be very small (for example, 16 KB); it is not dependent on a large gRPC frame.

Actual result

The consumer receives:

org.apache.dubbo.rpc.StatusRpcException: UNKNOWN : gRPC frame header malformed:
reserved bits not zero
    at org.apache.dubbo.rpc.TriRpcStatus.asException(TriRpcStatus.java:260)
    at org.apache.dubbo.rpc.protocol.tri.call.ObserverToClientCallListenerAdapter.onClose(
        ObserverToClientCallListenerAdapter.java:52)
    at org.apache.dubbo.rpc.protocol.tri.call.TripleClientCall.onComplete(
        TripleClientCall.java:126)
    at org.apache.dubbo.rpc.protocol.tri.stream.AbstractTripleClientStream$
        ClientTransportListener.finishProcess(AbstractTripleClientStream.java:224)


The provider 

<!-- Failed to upload "dubbo-triple-first-call-repro-standalone.zip" -->

receives:

[dubbo-triple-first-call-repro-standalone.zip](https://github.com/user-attachments/files/30777940/dubbo-triple-first-call-repro-standalone.zip)

io.netty.util.IllegalReferenceCountException: refCnt: 0
    at io.netty.buffer.AbstractByteBuf.ensureAccessible(AbstractByteBuf.java:1454)
    at io.netty.buffer.ByteBufInputStream.read(ByteBufInputStream.java:183)
    at org.apache.dubbo.remoting.http12.CompositeInputStream.read(
        CompositeInputStream.java:82)
    at org.apache.dubbo.remoting.http12.message.LengthFieldStreamingDecoder
        .processHeader(LengthFieldStreamingDecoder.java:147)
    at org.apache.dubbo.remoting.http12.message.LengthFieldStreamingDecoder
        .deliver(LengthFieldStreamingDecoder.java:117)
    at org.apache.dubbo.remoting.http12.message.LengthFieldStreamingDecoder
        .decode(LengthFieldStreamingDecoder.java:69)
    at org.apache.dubbo.rpc.protocol.tri.h12.http2.
        GenericHttp2ServerTransportListener$StreamingHttpMessageListener.onMessage(
        GenericHttp2ServerTransportListener.java:220)

### What you expected to happen

The first client-streaming Triple call after a consumer restart should be handled
the same as subsequent calls.

The provider should retain the received buffers until
`LengthFieldStreamingDecoder` finishes decoding them, so no malformed gRPC frame
is reported and no `IllegalReferenceCountException: refCnt: 0` occurs.

If a transport failure does occur, it should be propagated through the normal
stream error callback so that application resources can be released safely.

### Anything else

- Apache Dubbo: 3.3.6
- JDK: 17
- Transport: Triple / HTTP2
- Provider and consumer run in separate JVM processes.
- The failure also occurs with a 16 KB payload, so it does not appear to be
  caused by exceeding the default gRPC frame-size limit.
- We reproduced it with both native `tri` and single-port `dubbo` plus
  `ext-protocol: tri`; therefore it does not appear to be specific to the
  single-port configuration.
- The minimal two-process demo is nondeterministic, but the production symptom
  consistently occurs on the first call after the consumer restarts. We can
  provide the demo if needed.

### Do you have a (mini) reproduction demo?

- [x] Yes, I have a minimal reproduction demo to help resolve this issue more effectively!

### Are you willing to submit a pull request to fix on your own?

- [x] Yes I am willing to submit a pull request on my own!

### Code of Conduct

- [x] I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct)

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedEverything needs help from contributors

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions