#16447·dubbo

[Bug] Negative frame data length causes IllegalArgumentException in ExchangeCodec

Author: L1nq0Created Sep 4, 2026Updated Sep 4, 2026
Labelstype/need-triagecomponent/need-triage

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

Dubbo Java 3.3.6 (tag dubbo-3.3.6); the same code is unchanged on the 3.3 branch (checked today). OpenJDK 21, Linux. Protocol: dubbo.

Steps to reproduce this issue

While testing how the dubbo protocol codec handles invalid frames locally, we found that a frame whose header declares a negative data length makes decode throw IllegalArgumentException before decodeBody is reached.

A complete minimal frame is 16 bytes:

da bb c2 00 ff ff ff ff ff ff ff ff ff ff ff ff

magic dabb, flag c2 (request, twoway, hessian2), requestId all ff, and the data length field at offset 12 set to ffffffff, which reads back as -1.

Passing these bytes to DubboCodec.decode, or writing them to a provider port over TCP, throws:

java.lang.IllegalArgumentException: length: -1
    at org.apache.dubbo.remoting.buffer.ChannelBufferInputStream.<init>(ChannelBufferInputStream.java:37)
    at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:134)
    at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:92)

On the netty4 transport the exception leaves the codec and is handled as a connection-level exception (logged, connection closed).

What you expected to happen

A header declaring a negative data length is not a valid frame, and no additional input can make it one. decode should reject such a frame as invalid at the point the length is read, instead of letting a stream constructor throw an uncaught IllegalArgumentException from inside the codec. A sign check on len right after Bytes.bytes2int would cover it; returning NEED_MORE_INPUT would not fit here, since it would leave the channel waiting for input that can never make a negative length valid.

Anything else

Root cause, in ExchangeCodec (dubbo-remoting-api, tag dubbo-3.3.6):

  • line 119: the data length is read as a signed int (Bytes.bytes2int(header, 12))
  • line 123: finishRespWhenOverPayload only compares against the payload upper bound, and only for responses
  • line 129: the completeness check (readable < len + 16) passes for every negative len
  • line 134: ChannelBufferInputStream rejects negative lengths with IllegalArgumentException, which escapes decode

We have the 16-byte reproducer and a direct codec call available as a minimal demo, and are willing to submit a PR with the check and a test.

Do you have a (mini) reproduction demo?

  • 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?

  • Yes I am willing to submit a pull request on my own!

Code of Conduct