PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
Scale must not be negative
Error message
Scale must not be negative
What it means
PageSetup::setScale() stores the print zoom percentage for a worksheet. Excel's UI only permits 10-400, but the file format tolerates any non-negative integer (0 is written and Excel reads it as 100) and null resets to 100; the only rejected input is a negative integer, which throws 'Scale must not be negative'. Note that a successful setScale($scale, true) also disables fitToPage.
Source
Thrown at src/PhpSpreadsheet/Worksheet/PageSetup.php:353
* Set Scale.
* Print scaling. Valid values range from 10 to 400
* This setting is overridden when fitToWidth and/or fitToHeight are in use.
*
* @param bool $update Update fitToPage so scaling applies rather than fitToHeight / fitToWidth
*
* @return $this
*/
public function setScale(?int $scale, bool $update = true): static
{
// Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,
// but it is apparently still able to handle any scale >= 0, where 0 results in 100
if ($scale === null || $scale >= 0) {
$this->scale = $scale;
if ($update) {
$this->fitToPage = false;
}
} else {
throw new PhpSpreadsheetException('Scale must not be negative');
}
return $this;
}
/**
* Get Fit To Page.
*/
public function getFitToPage(): bool
{
return $this->fitToPage;
}
/**
* Set Fit To Page.
*
* @return $this
*/View on GitHub (pinned to 65b080eef4)
Solutions
- Clamp before setting: setScale(max(0, $scale)).
- If the goal is automatic sizing, use setFitToPage/setFitToWidth/setFitToHeight instead of computing a scale.
- Validate and cast numeric input before it reaches page setup.
Example fix
// before $sheet->getPageSetup()->setScale($zoom); // $zoom = -20 -> throws // after $sheet->getPageSetup()->setScale(max(0, (int) $zoom));
Defensive patterns
Strategy: validation
Validate before calling
$scale = max(0, (int) $zoom); $sheet->getPageSetup()->setScale($scale);
Type guard
function isValidPrintScale(?int $scale): bool
{
return $scale === null || $scale >= 0;
} Try / catch
try {
$sheet->getPageSetup()->setScale($scale);
} catch (PhpSpreadsheetException $e) {
$sheet->getPageSetup()->setScale(100);
} Prevention
- Clamp scale with max(0, ...) at the input boundary
- For automatic page fitting use setFitToWidth/setFitToHeight instead of computed percentages
- Remember scale 0 is legal and written as-is; Excel reads it as 100
When it happens
Trigger: $sheet->getPageSetup()->setScale(-15); a computed percentage going negative (e.g. 100 - $reduction * 100 style math); unvalidated user input like '-50' cast to int.
Common situations: Zoom derived arithmetically from data or request parameters; sanitized-too-late form input; porting code from libraries that clamped silently.
Related errors
- Requested Print Area does not exist
- Cell coordinate must not specify a worksheet.
- Cell coordinate must be a range of cells.
- Cell coordinate must not be absolute.
- Invalid index for setting print range.
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/cfc3519816151383.
Report an issue: GitHub.