YunaiV/ruoyi-vue-pro · warning · IllegalStateException
[createDecodeParser][消息体不能为空]
Error message
[createDecodeParser][消息体不能为空]
What it means
During length-field decoding, after computing frameBodyLength = readLength(...) + lengthAdjustment, a result of exactly ZERO is rejected as an empty body. This fires when the decoded length field plus adjustment equals zero — the device sent a zero-length body, or lengthAdjustment cancels out a legitimate small length value.
Source
Thrown at yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/codec/length/IotTcpLengthFieldFrameCodec.java:87
final AtomicReference<Integer> bodyLength = new AtomicReference<>(null); // 消息体长度,null 表示读取头部阶段
final AtomicReference<Buffer> headerBuffer = new AtomicReference<>(null); // 头部消息
// 处理读取到的数据
parser.handler(buffer -> {
if (bodyLength.get() == null) {
// 阶段 1: 读取头部,解析长度字段
headerBuffer.set(buffer.copy());
int length = readLength(buffer, lengthFieldOffset, lengthFieldLength);
int frameBodyLength = length + lengthAdjustment;
// 检查帧长度是否合法
if (frameBodyLength < 0) {
throw new IllegalStateException(String.format(
"[createDecodeParser][帧长度异常,length: %d, frameBodyLength: %d]",
length, frameBodyLength));
}
// 消息体为空,抛出异常
if (frameBodyLength == 0) {
throw new IllegalStateException("[createDecodeParser][消息体不能为空]");
}
// 【重要】切换到读取消息体模式
bodyLength.set(frameBodyLength);
parser.fixedSizeMode(frameBodyLength);
} else {
// 阶段 2: 读取消息体,组装完整帧
Buffer frame = processFrame(headerBuffer.get(), buffer);
// 重置状态,准备读取下一帧
bodyLength.set(null);
headerBuffer.set(null);
parser.fixedSizeMode(headerLength);
// 【重要】处理完整消息
handler.handle(frame);
}
});
parser.exceptionHandler(ex -> {View on GitHub (pinned to 0418084e22)
Solutions
- Confirm lengthAdjustment matches the protocol — often 0 when the length field already represents the body size.
- If zero-body frames are valid in your protocol, relax the codec to handle frameBodyLength==0 (emit an empty body to the handler instead of throwing).
- Check the device isn't emitting a malformed length due to a firmware bug (capture traffic).
Example fix
// before: zero-length body throws
if (frameBodyLength == 0) {
throw new IllegalStateException("[createDecodeParser][消息体不能为空]");
}
// after: allow zero-body frames if your protocol supports them
if (frameBodyLength == 0) {
Buffer frame = processFrame(headerBuffer.get(), Buffer.buffer());
bodyLength.set(null);
headerBuffer.set(null);
parser.fixedSizeMode(headerLength);
handler.handle(frame);
return;
} Defensive patterns
Strategy: validation
Validate before calling
// confirm lengthAdjustment matches the protocol before deploying
// most commonly 0 when the length field already encodes body size
if (lengthAdjustment != 0) {
log.warn("lengthAdjustment={}, 确认与设备协议一致", lengthAdjustment);
} Prevention
- Confirm lengthAdjustment against the device datasheet (often 0).
- If the protocol allows zero-body frames (heartbeats), relax the codec to emit an empty body instead of throwing.
- Capture traffic to confirm whether length=0 is a device bug or a valid control frame.
When it happens
Trigger: Device sends length=0 with adjustment=0; lengthAdjustment configured to exactly negate a legitimate length value (e.g. length includes header bytes and adjustment subtracts them, netting zero for small frames); device emits a valid heartbeat/keepalive frame with no body that this codec rejects.
Common situations: Misconfigured lengthAdjustment; device protocol legitimately allows zero-body control/heartbeat frames; device firmware bug emitting length=0.
Related errors
- [createDecodeParser][帧长度异常,length: %d, frameBodyLength: %d]
- 数据长度 %d 超过固定长度 %d
- [createDecodeParser][解析异常]
- 不支持的长度字段长度: {}
- [createDecodeParser][解析异常]
AI-assisted analysis of YunaiV/ruoyi-vue-pro@0418084e22 (2026-08-14).
Data as JSON: /api/errors/33b4a45c7af46ac2.
Report an issue: GitHub.