{"record":{"id":"ee621fa67131b14c","repo":"apache/druid","slug":"frametoolarge-ee621f","errorCode":"FrameTooLarge","errorMessage":"FrameRowTooLargeException: row too large for frame allocator capacity %s","messagePattern":"FrameRowTooLargeException: row too large for frame allocator capacity (.+?)","errorType":"error_code","errorClass":"FrameRowTooLargeException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/querykit/common/OffsetLimitFrameProcessor.java","lineNumber":153,"sourceCode":"    } else if (startRow == 0\n               && endRow == frame.numRows()\n               && inputSignatureMatchesOutputSignature\n               && frameWriterFactory.frameType().equals(frame.type())) {\n      // Want the whole frame; emit it as-is.\n      rowsProcessedSoFar += frame.numRows();\n      return frame;\n    }\n\n    final Cursor cursor = FrameProcessors.makeCursor(frame, frameReader);\n\n    long rowsProcessedSoFarInFrame = 0;\n\n    try (final FrameWriter frameWriter = frameWriterFactory.newFrameWriter(cursor.getColumnSelectorFactory())) {\n      while (!cursor.isDone() && rowsProcessedSoFarInFrame < endRow) {\n        if (rowsProcessedSoFarInFrame >= startRow && !frameWriter.addSelection()) {\n          // Don't retry; it can't work because the allocator is unlimited anyway.\n          // Also, I don't think this line can be reached, because the allocator is unlimited.\n          throw new FrameRowTooLargeException(frameWriterFactory.allocatorCapacity());\n        }\n\n        cursor.advance();\n        rowsProcessedSoFarInFrame++;\n      }\n\n      rowsProcessedSoFar += rowsProcessedSoFarInFrame;\n      return Frame.wrap(frameWriter.toByteArray());\n    }\n  }\n}\n","sourceCodeStart":135,"sourceCodeEnd":165,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/querykit/common/OffsetLimitFrameProcessor.java#L135-L165","documentation":"In the offset/limit frame processor, after skipping to startRow the processor writes rows up to endRow into a fresh frame writer whose allocator is unlimited; if addSelection() still fails the code intentionally throws FrameRowTooLargeException rather than retrying, because with an unlimited allocator failure indicates a logical bug or a truly unrepresentable row.","triggerScenarios":"An offset/limit stage over a cursor whose current row cannot be added to the frame despite the unlimited frame allocator — normally an internal invariant breach (row larger than any allocation) reached while processing rows between startRow and endRow.","commonSituations":"Very large single rows flowing through an MSQ limit/offset stage; typically surfaces as an engine bug report rather than user misconfiguration, but can accompany extremely wide rows near allocator limits.","solutions":["Retry the query; if reproducible, file a Druid bug with the query and stack trace","Reduce row width (fewer/smaller columns) before the limit/offset stage","Increase MSQ memory limits in case the allocator is not truly unlimited in your configuration","Check Druid version for known fixes to OffsetLimitFrameProcessor"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  runMsqQuery(query);\n} catch (MSQException e) {\n  if (e.getFault() instanceof FrameTooLarge && stageIsOffsetLimit(e)) {\n    // not user-fixable; capture query+trace and report to Druid\n  }\n}","preventionTips":["Avoid pathological ultra-wide rows in limit/offset stages","Keep Druid upgraded to pick up frame-processor fixes","Reduce projections before offset/limit stages"],"tags":["msq","frame-processor","memory","internal-error"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}