apache/druid · error · IOException
Input stream is null
Error message
Input stream is null
What it means
BloomKFilter.deserialize(InputStream) validates its input before parsing the binary bloom filter format and throws IOException('Input stream is null') when given a null stream. The binary format (numHashFunc byte, bitset length int, then longs) cannot be read from a null source, so it fails fast.
Source
Thrown at extensions-core/druid-bloom-filter/src/main/java/org/apache/druid/query/filter/BloomKFilter.java:163
dataOutputStream.writeInt(bloomFilter.getBitSet().length);
for (long value : bloomFilter.getBitSet()) {
dataOutputStream.writeLong(value);
}
}
/**
* Deserialize a bloom filter
* Read a byte stream, which was written by {@linkplain #serialize(OutputStream, BloomKFilter)}
* into a {@code BloomKFilter}
*
* @param in input bytestream
*
* @return deserialized BloomKFilter
*/
public static BloomKFilter deserialize(InputStream in) throws IOException
{
if (in == null) {
throw new IOException("Input stream is null");
}
try {
DataInputStream dataInputStream = new DataInputStream(in);
int numHashFunc = dataInputStream.readByte();
int bitsetArrayLen = dataInputStream.readInt();
long[] data = new long[bitsetArrayLen];
for (int i = 0; i < bitsetArrayLen; i++) {
data[i] = dataInputStream.readLong();
}
return new BloomKFilter(data, numHashFunc);
}
catch (RuntimeException e) {
IOException io = new IOException("Unable to deserialize BloomKFilter");
io.initCause(e);
throw io;
}
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Check the stream for null before calling deserialize and treat null as 'no filter' (create an empty BloomKFilter(maxNumEntries) instead)
- Fix the upstream producer so a valid serialized filter is always stored (empty filter rather than null)
- Add logging/assertions where the stream is created to find why it is null
Example fix
// before BloomKFilter filter = BloomKFilter.deserialize(in); // NPE/IOE when in == null // after BloomKFilter filter = (in == null) ? new BloomKFilter(maxNumEntries) : BloomKFilter.deserialize(in);
Defensive patterns
Strategy: type-guard
Validate before calling
// Java guard before deserializing
if (in == null) { return new BloomKFilter(maxNumEntries); } // empty filter fallback Type guard
static boolean isReadable(InputStream in) { return in != null; } Try / catch
try {
return BloomKFilter.deserialize(in);
} catch (IOException e) {
if ("Input stream is null".equals(e.getMessage())) {
return new BloomKFilter(maxNumEntries); // treat as no filter
}
throw e;
} Prevention
- Null-check streams returned from DB/blob lookups before deserializing
- Default missing payloads to an empty BloomKFilter(maxNumEntries)
- Log when the source payload is absent to fix producers
When it happens
Trigger: Calling BloomKFilter.deserialize(null), e.g. when a lookup/base64-decoded payload or byte source produced null (missing column value, failed decode, unset variable) and the result is passed straight into deserialize.
Common situations: Reading persisted bloom filter payloads from a database/blob store where the row has no filter stored; deserializing an optional JSON field that was absent; wrapping a base64 field that failed to decode and left the stream null.
Related errors
- unknown event type [%s]
- interrupted flushing elements from queue
- Failed to deserialize V%s column.
- Failed to deserialize V%s column.
- Failed to deserialize V%s column.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/3fe617a6d1b44e84.
Report an issue: GitHub.