PHPOffice/PhpSpreadsheet · warning · PhpOffice\PhpSpreadsheet\Exception

Start column ( ) is beyond highest column ( )

Error message

Start column ({$startColumn}) is beyond highest column ({$this->worksheet->getHighestColumn()})

What it means

ColumnIterator::resetStart() converts the requested start column to a numeric index and compares it with the worksheet's highest column. A start column to the right of the highest used column leaves nothing to iterate, so it throws with both addresses in the message.

Solutions

  1. Start at or before the highest column: $sheet->getColumnIterator('A') or pass a column within range
  2. Derive the start dynamically: min of your desired column and $sheet->getHighestColumn() by index comparison
  3. Guard with Coordinate::columnIndexFromString($start) <= Coordinate::columnIndexFromString($sheet->getHighestColumn())

Example fix

// before
$iterator = $sheet->getColumnIterator()->resetStart('Z');

// after
$start = 'A';
if (\PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString('Z') <= \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($sheet->getHighestColumn())) {
    $start = 'Z';
}
$iterator = $sheet->getColumnIterator($start);
Defensive patterns

Strategy: validation

Validate before calling

use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
$maxIdx = Coordinate::columnIndexFromString($sheet->getHighestColumn());
$wantIdx = Coordinate::columnIndexFromString($startColumn);
if ($wantIdx > $maxIdx) {
    $startColumn = 'A'; // or throw, depending on your policy
}
$iterator = $sheet->getColumnIterator($startColumn);

Type guard

function columnWithinSheet(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet, string $column): bool
{
    return \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($column)
        <= \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($sheet->getHighestColumn());
}

Try / catch

try {
    $iterator->resetStart($startColumn);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
    $iterator->resetStart('A');
}

Prevention

When it happens

Trigger: $sheet->getColumnIterator()->resetStart('Z') on a sheet whose getHighestColumn() is 'D'; also resetStart() after content shrinks.

Common situations: Hard-coded start columns for sheets with varying widths; running column iteration after deleting columns or on freshly created empty sheets.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/3f6cdb50d9b5b069. Report an issue: GitHub.

Appendix: source

Thrown at src/PhpSpreadsheet/Worksheet/ColumnIterator.php:69

     * Destructor.
     */
    public function __destruct()
    {
        unset($this->worksheet);
    }

    /**
     * (Re)Set the start column and the current column pointer.
     *
     * @param string $startColumn The column address at which to start iterating
     *
     * @return $this
     */
    public function resetStart(string $startColumn = 'A'): static
    {
        $startColumnIndex = Coordinate::columnIndexFromString($startColumn);
        if ($startColumnIndex > Coordinate::columnIndexFromString($this->worksheet->getHighestColumn())) {
            throw new Exception(
                "Start column ({$startColumn}) is beyond highest column ({$this->worksheet->getHighestColumn()})"
            );
        }

        $this->startColumnIndex = $startColumnIndex;
        if ($this->endColumnIndex < $this->startColumnIndex) {
            $this->endColumnIndex = $this->startColumnIndex;
        }
        $this->seek($startColumn);

        return $this;
    }

    /**
     * (Re)Set the end column.
     *
     * @param ?string $endColumn The column address at which to stop iterating
     *

View on GitHub (pinned to 65b080eef4)