apple/pkl · error · DecodeException
malformedMessageHeaderException
malformedMessageHeaderException
Error message
malformedMessageHeaderException
What it means
The first element of a message frame must be an integer message code. If unpackInt() hits a value of a different MessagePack type, a MessageTypeException is wrapped as DecodeException with code malformedMessageHeaderException.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/messaging/AbstractMessagePackDecoder.java:64
protected abstract @Nullable Message decodeMessage(Type msgType, Map<Value, Value> map)
throws DecodeException, URISyntaxException;
@Override
public @Nullable Message decode() throws IOException, DecodeException {
if (!unpacker.hasNext()) {
return null;
}
int code;
try {
var arraySize = unpacker.unpackArrayHeader();
if (arraySize != 2) {
throw new DecodeException(ErrorMessages.create("malformedMessageHeaderLength", arraySize));
}
code = unpacker.unpackInt();
} catch (MessageTypeException e) {
throw new DecodeException(ErrorMessages.create("malformedMessageHeaderException"), e);
}
Type msgType;
try {
msgType = Type.fromInt(code);
} catch (IllegalArgumentException e) {
throw new DecodeException(
ErrorMessages.create("malformedMessageHeaderUnrecognizedCode", Integer.toHexString(code)),
e);
}
try {
var map = unpacker.unpackValue().asMapValue().map();
var decoded = decodeMessage(msgType, map);
if (decoded != null) {
return decoded;
}
throw new DecodeException(View on GitHub (pinned to f3efcbfc9b)
Solutions
- Confirm the peer writes [int, map] frames with an integer first element
- Check you are reading from the binary channel, not a text/log stream
- Re-capture or regenerate the stream; inspect bytes at the failure offset
- Upgrade the peer library so both sides use the same message format
Example fix
// before: trusting the header code
var code = unpacker.unpackInt();
// after: guard against type errors upstream
if (!nextValueIsInteger(unpacker)) throw new IllegalStateException("expected integer message code, got " + describeNext(unpacker)); Defensive patterns
Strategy: validation
Validate before calling
// peek: first frame element must be an integer code boolean headerIsInt = peekNextTypeIsInteger(unpacker);
Try / catch
try { return decoder.decode(unpacker); } catch (DecodeException e) { if (String.valueOf(e.getMessage()).contains("malformedMessageHeaderException")) { log.error("corrupt msgpack header at offset {}", bytesRead); } throw e; } Prevention
- Keep binary msgpack channels separate from text/logging output
- Checksum or validate captured streams
- Use matching library versions on both ends
When it happens
Trigger: Decoding a frame whose array element 0 is a string, nil, map, etc. instead of an integer code.
Common situations: Corrupted or hand-edited message files, wrong stream interleaving (e.g. reading stdout text into the msgpack channel), or peer encoding with an incompatible schema.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- malformedMessageHeaderLength
- malformedMessageHeaderUnrecognizedCode
- unhandledMessageCode
- malformedMessageBody
- missingMessageParameter
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/6fb19c8e48564255.
Report an issue: GitHub.