openzipkin/zipkin · error · IllegalArgumentException
Malformed: invalid boolean value at byte
Error message
Malformed: invalid boolean value at byte
What it means
In proto3, a bool field is a single varint byte that must be 0 or 1. Proto3Fields.BoolField.read throws 'Malformed: invalid boolean value at byte N' when it reads a byte outside that range (e.g. 2..255 or a negative byte). This points to a producer encoding booleans incorrectly or, again, a misaligned stream.
Source
Thrown at zipkin/src/main/java/zipkin2/internal/Proto3Fields.java:265
BooleanField(int key) {
super(key);
assert wireType == WIRETYPE_VARINT;
}
int sizeInBytes(boolean bool) {
return bool ? 2 : 0; // tag + varint
}
void write(WriteBuffer b, boolean bool) {
if (!bool) return;
b.writeByte(key);
b.writeByte(1);
}
boolean read(ReadBuffer b) {
byte bool = b.readByte();
if (bool < 0 || bool > 1) {
throw new IllegalArgumentException("Malformed: invalid boolean value at byte " + b.pos());
}
return bool == 1;
}
}
// added for completion as later we will skip fields we don't use
static final class Fixed32Field extends Field {
Fixed32Field(int key) {
super(key);
assert wireType == WIRETYPE_FIXED32;
}
int sizeInBytes(int number) {
if (number == 0) return 0;
return 1 + 4; // tag + 4 byte number
}
}
View on GitHub (pinned to 878ce2a1fa)
Solutions
- Check the byte offset in the message; verify the bytes immediately before it (the field tag) match the expected bool field key.
- Ensure producers encode bools as exactly one byte (0x00/0x01) — prefer SpanBytesEncoder.PROTO3.
- If interoperating with protoc-based clients, confirm they use the official zipkin2.proto and do not pack bools into varints > 1 byte.
- Reject/quarantine the message in collector code; do not retry it, deterministic corruption will not heal.
Example fix
// before // hand-rolled: wrote debug flag as int varint writeVarint(debug ? 2 : 0); // after // proto3 bool: single byte, 1 or 0 buffer.writeByte(key); buffer.writeByte(debug ? 1 : 0);
Defensive patterns
Strategy: validation
Validate before calling
// if you control the bytes, assert the bool byte before decode is impractical; instead validate at encode time
void writeBool(WriteBuffer b, int key, boolean v) { b.writeByte(key); b.writeByte(v ? 1 : 0); } Try / catch
catch (IllegalArgumentException e) { if (e.getMessage().contains("invalid boolean")) { LOG.warn("bad bool encoding from producer"); drop(); } else throw e; } Prevention
- Encode proto3 bools as a single byte 0/1 only.
- Use protoc-generated classes for cross-language producers.
- Fuzz your collector with random bytes in staging to verify graceful drops.
When it happens
Trigger: Decoding a proto3 Span whose 'debug' or 'shared' field (bool fields in zipkin2.proto) contains a varint other than 0/1, e.g. a truncated two-byte varint where the second byte is read as the bool.
Common situations: Custom encoders writing boolean flags as multi-byte varints or as raw integers; schema drift where a non-bool field's bytes are read as bool after misalignment; fuzzed payloads.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Malformed: fieldNumber was zero at byte
- Malformed: invalid wireType
- hex field greater than 32 chars long: {}
- Greater than 32-bit varint at position {}
- Greater than 64-bit varint at position {}
AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14).
Data as JSON: /api/errors/cd66b6de4300b5b8.
Report an issue: GitHub.