apache/druid · error · IOException
Unable to deserialize BloomKFilter
Error message
Unable to deserialize BloomKFilter
What it means
BloomKFilter.deserialize() reads the header (numHashFunctions, bitset length) and the long[] bitset from the buffer inside a try block; any RuntimeException — most often a negative bitset length, buffer underflow, or invalid hash-function count caused by corrupt or truncated serialized bytes — is caught and rethrown as an IOException with this message. The faulty input is the serialized bloom filter bytes.
Solutions
- Check whether the serialized bloom filter bytes were truncated or corrupted in storage or transit
- Verify the filter was written by a compatible BloomKFilter version (header layout matches BIG_ENDIAN expectations)
- Re-aggregate or re-ingest the affected data to regenerate valid filters
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at extensions-core/druid-bloom-filter/src/main/java/org/apache/druid/query/filter/BloomKFilter.java:285 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/6c477844d4045374.
Report an issue: GitHub.
Appendix: source
Thrown at extensions-core/druid-bloom-filter/src/main/java/org/apache/druid/query/filter/BloomKFilter.java:285
public static BloomKFilter deserialize(ByteBuffer in, int position) throws IOException
{
if (in == null) {
throw new IOException("Input stream is null");
}
try {
ByteBuffer dataBuffer = in.duplicate().order(ByteOrder.BIG_ENDIAN);
dataBuffer.position(position);
int numHashFunc = dataBuffer.get();
int bitsetArrayLen = dataBuffer.getInt();
long[] data = new long[bitsetArrayLen];
for (int i = 0; i < bitsetArrayLen; i++) {
data[i] = dataBuffer.getLong();
}
return new BloomKFilter(data, numHashFunc);
}
catch (RuntimeException e) {
throw new IOException("Unable to deserialize BloomKFilter", e);
}
}
/**
* Merges BloomKFilter bf2Buffer into bf1Buffer in place. Does not mutate buffer positions.
* Assumes 2 BloomKFilters with the same size/hash functions are serialized to ByteBuffers
*
* @param bf1Buffer
* @param bf1Start
* @param bf2Buffer
* @param bf2Start
*/
public static void mergeBloomFilterByteBuffers(
ByteBuffer bf1Buffer,
int bf1Start,
ByteBuffer bf2Buffer,
int bf2Start
)View on GitHub (pinned to 9b90983fd2)