apache/beam · error · CoderException
NullableCoder expects either a byte valued 0 (null) or 1 (pr
Error message
NullableCoder expects either a byte valued 0 (null) or 1 (present), got %s
What it means
NullableCoder's decode() reads one byte that must be 0 (ENCODE_NULL) or 1 (ENCODE_PRESENT). Any other value means the stream is corrupt, truncated, or was not written by NullableCoder, so decoding cannot proceed. This is a data-integrity failure, not an application-logic error.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/NullableCoder.java:89
} else {
outStream.write(ENCODE_PRESENT);
valueCoder.encode(value, outStream, context);
}
}
@Override
public @Nullable T decode(InputStream inStream) throws IOException, CoderException {
return decode(inStream, Context.NESTED);
}
@Override
public @Nullable T decode(InputStream inStream, Context context)
throws IOException, CoderException {
int b = inStream.read();
if (b == ENCODE_NULL) {
return null;
} else if (b != ENCODE_PRESENT) {
throw new CoderException(
String.format(
"NullableCoder expects either a byte valued %s (null) or %s (present), got %s",
ENCODE_NULL, ENCODE_PRESENT, b));
}
return valueCoder.decode(inStream, context);
}
@Override
public List<Coder<T>> getCoderArguments() {
return ImmutableList.of(valueCoder);
}
/**
* {@code NullableCoder} is deterministic if the nested {@code Coder} is.
*
* <p>{@inheritDoc}
*/
@OverrideView on GitHub (pinned to 12126d8942)
Solutions
- Re-run the pipeline from a source rather than resuming from state encoded with an incompatible coder version
- Verify the InputStream is positioned exactly at the start of the NullableCoder-encoded value (no earlier fields were skipped)
- Check that the writer and reader use the same coder version (same Beam release for state/backup data)
Example fix
// before Coder<T> coder = myCoder; // changed from NullableCoder.of(...), old state unreadable // after // re-run pipeline from source, or keep the same coder: Coder<T> coder = NullableCoder.of(innerCoder); // matches previously written bytes
Defensive patterns
Strategy: try-catch
Validate before calling
// No pre-call check possible on a raw stream; verify the coder matches the writer's coder version
Type guard
null
Try / catch
try { T v = nullableCoder.decode(in, Context.OUTER); } catch (CoderException e) { /* treat stream as corrupt: re-read from source */ } Prevention
- Keep coder versions stable across pipeline deploys for stateful/streaming jobs
- Never hand-edit or partially read encoded byte streams
- Re-run from source rather than decoding legacy state after coder changes
When it happens
Trigger: Decoding a byte stream whose first byte is not 0x00 or 0x01: e.g. stream produced by a different coder, an out-of-sync InputStream offset, byte corruption, or version mismatch between writer and reader coder.
Common situations: Changing a pipeline's coder (e.g. adding/removing NullableCoder) without re-running from scratch, so old checkpoints/state are decoded with the new coder; byte-stream truncation; manual wire-format fiddling.
Related errors
- cannot encode a null Byte
- cannot estimate size for unsupported null value
- NonDeterministicException(target, message, e)
- Unable to encode element '" + value + "' with coder '" + thi
- Unable to provide coder for %s, this factory can only provid
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/060bbf39fd0c30c5.
Report an issue: GitHub.