apache/druid · error · IllegalArgumentException
Invalid table size[ ]
Error message
Invalid table size[%s]
What it means
TableLongEncodingReader decodes a table-encoded long column from a ByteBuffer. The header's tableSize must be between 0 and CompressionFactory.MAX_TABLE_SIZE; anything else indicates corrupt or malformed segment data, so the constructor fails fast with this IAE instead of allocating an unbounded array.
Solutions
- Re-download / reload the affected segment (delete from segment cache so it is re-fetched)
- Verify segment integrity and re-ingest the datasource if corruption persists
- Check the buffer alignment/version of whatever produced the ByteBuffer being read
- Confirm the writer and reader Druid versions are compatible
Example fix
// before ColumnHolder holder = segmentLoader.getColumnator().read(file); // throws on corrupt segment // after // validate & re-fetch the segment: segmentManager.dropSegment(descriptor); // then allow the loader to re-download a fresh copy before retrying reads
Defensive patterns
Strategy: try-catch
Validate before calling
// validate the header before constructing:
int tableSize = buf.duplicate().position(pos+1).getInt();
if (tableSize < 0 || tableSize > CompressionFactory.MAX_TABLE_SIZE) { reloadSegment(); } Try / catch
try { new TableLongEncodingReader(buf); } catch (IAE e) { log.error("corrupt table-encoded column, reloading segment"); reloadAndRetry(); } Prevention
- Verify segment checksums on download
- Reload the segment cache entry on parse failure
- Keep writer/reader Druid versions aligned
When it happens
Trigger: Reading a column whose serialized header contains a tableSize < 0 or > MAX_TABLE_SIZE, typically from a corrupted segment file, truncated/misaligned buffer, or data written by an incompatible writer.
Common situations: Segments corrupted on disk or in deep storage; hand-editing or mis-parsing column buffers; loading a foreign/garbage file as a Druid segment.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Metric[ ] loaded up metric[ ] from disk. File names do…
- Actual Row count mismatch. Expected
- Attempt to add row to swapped-out sink for segment
- Cannot read frame of size [%,d] bytes
- Column capacity exceeded
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/00586178c8c7ef45.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/data/TableLongEncodingReader.java:40
import org.apache.druid.java.util.common.IAE;
import java.nio.ByteBuffer;
public class TableLongEncodingReader implements CompressionFactory.LongEncodingReader
{
private final long[] table;
private final int bitsPerValue;
private final ByteBuffer buffer;
private VSizeLongSerde.LongDeserializer deserializer;
public TableLongEncodingReader(ByteBuffer fromBuffer)
{
this.buffer = fromBuffer.asReadOnlyBuffer();
byte version = buffer.get();
if (version == CompressionFactory.TABLE_ENCODING_VERSION) {
int tableSize = buffer.getInt();
if (tableSize < 0 || tableSize > CompressionFactory.MAX_TABLE_SIZE) {
throw new IAE("Invalid table size[%s]", tableSize);
}
bitsPerValue = VSizeLongSerde.getBitsForMax(tableSize);
table = new long[tableSize];
for (int i = 0; i < tableSize; i++) {
table[i] = buffer.getLong();
}
fromBuffer.position(buffer.position());
deserializer = VSizeLongSerde.getDeserializer(bitsPerValue, buffer, buffer.position());
} else {
throw new IAE("Unknown version[%s]", version);
}
}
private TableLongEncodingReader(ByteBuffer buffer, long[] table, int bitsPerValue)
{
this.buffer = buffer;
this.table = table;
this.bitsPerValue = bitsPerValue;View on GitHub (pinned to 9b90983fd2)