PHPOffice/PhpSpreadsheet · warning · PhpOffice\PhpSpreadsheet\Exception
Row $row is out of range ({$this->startRow} - {$this->endRow
Error message
Row $row is out of range ({$this->startRow} - {$this->endRow}) What it means
ColumnCellIterator::seek() validates the requested row against the iterator's startRow/endRow bounds (defaults derived from the highest row of the column when the iterator was constructed). Seeking outside that window throws with the valid interval in the message.
Source
Thrown at src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php:100
}
/**
* Set the row pointer to the selected row.
*
* @param int $row The row number to set the current pointer at
*
* @return $this
*/
public function seek(int $row = 1): static
{
if (
$this->onlyExistingCells
&& (!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->columnIndex) . $row))
) {
throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
}
if (($row < $this->startRow) || ($row > $this->endRow)) {
throw new PhpSpreadsheetException("Row $row is out of range ({$this->startRow} - {$this->endRow})");
}
$this->currentRow = $row;
return $this;
}
/**
* Rewind the iterator to the starting row.
*/
public function rewind(): void
{
$this->currentRow = $this->startRow;
}
/**
* Return the current cell in this worksheet column.
*/
public function current(): ?CellView on GitHub (pinned to 65b080eef4)
Solutions
- Seek only within [$iterator->getStartRow()? use the boundaries] — obtain the current bounds or recreate the iterator with the needed range: new ColumnCellIterator($sheet, 'A', 1, 500)
- Validate $row against the sheet's highest row ([$sheet->getHighestRow()]) before seeking
- Iterate with foreach instead of seek() for sequential access
Example fix
// before $cellIterator->seek(500); // after $row = min(max($row, $cellIterator->getStartRow()), $cellIterator->getEndRow()); $cellIterator->seek($row);
Defensive patterns
Strategy: validation
Validate before calling
$row = max($iterator->getStartRow(), min($row, $iterator->getEndRow()));
if ($row < $iterator->getStartRow() || $row > $iterator->getEndRow()) {
throw new OutOfBoundsException("Row $row outside iterator bounds");
}
$iterator->seek($row); Type guard
function rowWithinIteratorBounds(\PhpOffice\PhpSpreadsheet\Worksheet\ColumnCellIterator $it, int $row): bool
{
return $row >= $it->getStartRow() && $row <= $it->getEndRow();
} Try / catch
try {
$iterator->seek($row);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
// recreate the iterator covering the requested row
$iterator = new \PhpOffice\PhpSpreadsheet\Worksheet\ColumnCellIterator($sheet, $column, 1, $sheet->getHighestRow());
$iterator->seek($row);
} Prevention
- Construct the iterator with the full row span you intend to seek within
- Clamp externally derived row numbers to the sheet's highest row
When it happens
Trigger: $cellIterator->seek(500) when the iterator covers rows 1-100; seeking to a row below startRow, e.g. seek(1) after the iterator was created with a start row of 10.
Common situations: Random-access navigation on an iterator built for a narrower range; row numbers computed from user input or other sheets assumed to match this column's extent.
Related errors
- Start column ({$startColumn}) is beyond highest column ({$th
- Cannot get row when cell is not bound to a worksheet
- In "IterateOnlyExistingCells" mode and Cell does not exist
- Cannot update when cell is not bound to a worksheet
- Cannot get column when cell is not bound to a worksheet
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/51e8d5746da0f08c.
Report an issue: GitHub.