{"record":{"id":"65f85e785311c4bd","repo":"apache/druid","slug":"column-d-is-not-a-valid-column-for-segment-s","errorCode":null,"errorMessage":"Column[%d] is not a valid column for segment[%s]","messagePattern":"Column\\[(.+?)\\] is not a valid column for segment\\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/join/table/BroadcastSegmentIndexedTable.java","lineNumber":194,"sourceCode":"  }\n\n  @Override\n  public int numRows()\n  {\n    return queryableIndex.getNumRows();\n  }\n\n  @Override\n  public Index columnIndex(int column)\n  {\n    return RowBasedIndexedTable.getKeyColumnIndex(column, keyColumnsIndexes);\n  }\n\n  @Override\n  public Reader columnReader(int column)\n  {\n    if (!rowSignature.contains(column)) {\n      throw new IAE(\"Column[%d] is not a valid column for segment[%s]\", column, segment.getId());\n    }\n    final SimpleAscendingOffset offset = new SimpleAscendingOffset(queryableIndex.getNumRows());\n    final BaseColumn baseColumn = queryableIndex.getColumnHolder(rowSignature.getColumnName(column)).getColumn();\n    final BaseObjectColumnValueSelector<?> selector = baseColumn.makeColumnValueSelector(offset);\n\n    return new Reader()\n    {\n      @Nullable\n      @Override\n      public Object read(int row)\n      {\n        offset.setCurrentOffset(row);\n        return selector.getObject();\n      }\n\n      @Override\n      public void close() throws IOException\n      {","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/join/table/BroadcastSegmentIndexedTable.java#L176-L212","documentation":"BroadcastSegmentIndexedTable.columnReader(int) validates the requested column index against the table's rowSignature. If the index is out of bounds (>= signature size or negative), Druid throws this IllegalArgumentException naming the segment, protecting downstream readers from selecting a nonexistent column.","triggerScenarios":"Calling columnReader with an int column index not present in the table's RowSignature, usually from a join key/column mapping computed against a different signature version than the loaded segment.","commonSituations":"Segment replaced/updated so its signature no longer matches the query's expected column order; join cache keys built before a broker/server restart with a changed table schema; bugs in key column index computation for broadcast tables.","solutions":["Verify the column index against rowSignature.size() before calling columnReader","Drop/rebuild the broadcast table or refresh cached joinables after schema changes so indexes match the current signature","Ensure join clause column ordering matches the broadcast segment's rowSignature"],"exampleFix":"// before\nreader = table.columnReader(3); // signature has 2 columns\n// after\nif (column < table.rowSignature().size()) { reader = table.columnReader(column); }","handlingStrategy":"validation","validationCode":"if (column < 0 || column >= table.rowSignature().size())\n  throw new IllegalArgumentException(\"column \" + column + \" out of range for broadcast table\");\nReader r = table.columnReader(column);","typeGuard":null,"tryCatchPattern":"try { r = table.columnReader(col); } catch (IAE e) { log.error(\"stale join table signature for segment {}\", e.getMessage()); refreshTable(); }","preventionTips":["Recompute join key indexes whenever a segment/table is reloaded","Invalidate join caches after schema changes","Compare the query's expected signature with rowSignature() before reading"],"tags":["java","join","broadcast","index","druid"],"backgroundTag":"index-out-of-range","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"}