apache/druid · error · IllegalStateException
Can't read row memory from frame. Wrong type or signature?
Error message
Can't read row memory from frame. Wrong type or signature?
What it means
Secondary guard in the same makeRowWeightSupplier path: the per-row MemoryRange supplier returned null for a row, so row memory could not be read for that frame row (wrong frame type or signature mismatch) while accumulating cluster-by statistics. Distinct from the construction-time check — here the failure occurs per-row at read time.
Solutions
- Treat as an engine bug: file a report including the query, stage number, and frame signature.
- Verify the input frame was produced by a compatible writer version; re-run the query to rule out corrupted frames.
- Avoid ORDER BY/cluster-by configurations that trigger row-memory statistics collection until fixed.
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/indexing/processor/KeyStatisticsCollectionProcessor.java:158 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/d528a86456d7d3c7.
Report an issue: GitHub.
Appendix: source
Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/indexing/processor/KeyStatisticsCollectionProcessor.java:158
final ColumnSelectorFactory columnSelectorFactory
)
{
final Supplier<MemoryRange<Memory>> rowMemorySupplier =
FrameReaderUtils.makeRowMemorySupplier(columnSelectorFactory, frameType, frameReader.signature());
final int numFields = frameReader.signature().size();
if (rowMemorySupplier == null) {
// Can't access row memory.
throw new ISE("Can't read row memory from frame. Wrong frame type or signature?");
}
return () -> {
final MemoryRange<Memory> rowMemory = rowMemorySupplier.get();
if (rowMemory == null) {
// Can't access row memory.
throw new ISE("Can't read row memory from frame. Wrong type or signature?");
}
long maxValueLength = 0;
long totalLength = 0;
long currentValueStartPosition = (long) Integer.BYTES * numFields;
for (int i = 0; i < numFields; i++) {
final long currentValueEndPosition = rowMemory.memory().getInt(rowMemory.start() + (long) Integer.BYTES * i);
final long valueLength = currentValueEndPosition - currentValueStartPosition;
if (valueLength > maxValueLength) {
maxValueLength = valueLength;
}
totalLength += valueLength;
currentValueStartPosition = currentValueEndPosition;
}
View on GitHub (pinned to 9b90983fd2)