PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Writer\Exception
Line ending must be \n (Unix) or \r\n (Windows)
Error message
Line ending must be \n (Unix) or \r\n (Windows)
What it means
The HTML writer serializes output using a line-ending setting restricted to exactly two sequences: Unix LF and Windows CRLF. setLineEnding() enforces that whitelist and throws for anything else, including a lone CR, an empty string, or markup like '<br>'. The default is PHP_EOL, which is always one of the accepted values on every platform.
Source
Thrown at src/PhpSpreadsheet/Writer/Html.php:92
*/
protected string $imagesRoot = '';
/**
* embed images, or link to images.
*/
protected bool $embedImages = false;
protected string $lineEnding = PHP_EOL;
public function getLineEnding(): string
{
return $this->lineEnding;
}
public function setLineEnding(string $lineEnding): self
{
if ($lineEnding != "\n" && $lineEnding !== "\r\n") {
throw new Exception('Line ending must be \n (Unix) or \r\n (Windows)');
}
$this->lineEnding = $lineEnding;
return $this;
}
protected bool $dataFormula = false;
public function setDataFormula(bool $dataFormula): self
{
$this->dataFormula = $dataFormula;
return $this;
}
protected bool $preserveFormatAndValue = false;
public function setPreserveFormatAndValue(bool $preserveFormatAndValue): selfView on GitHub (pinned to 65b080eef4)
Solutions
- Pass one of the two allowed literals: LF or CRLF.
- Omit the call entirely; the default PHP_EOL is always accepted.
- Whitelist configuration before applying it: only accept the two exact sequences, otherwise fall back to PHP_EOL or reject the config.
Example fix
// before
$writer->setLineEnding('<br>'); // throws: only LF or CRLF allowed
// after
$writer->setLineEnding(chr(10)); // LF, Unix
$writer->setLineEnding(chr(13) . chr(10)); // CRLF, Windows
// or omit the call: the default PHP_EOL is always accepted Defensive patterns
Strategy: validation
Validate before calling
$eol = $config['line_ending'] ?? PHP_EOL;
$allowed = [chr(10), chr(13) . chr(10)]; // LF, CRLF
if (!in_array($eol, $allowed, true)) {
$eol = PHP_EOL; // or reject the configuration value
}
$writer->setLineEnding($eol); Prevention
- Whitelist newline settings to the two exact sequences before applying them.
- Rely on the default PHP_EOL unless a specific output format requires CRLF.
- Do not share EOL constant lists with CSV code, which permits a lone CR.
When it happens
Trigger: setLineEnding() with a lone carriage return, an empty string, '<br>', or PHP_EOL concatenated with extra characters; passing a user-configurable newline setting straight from an export configuration screen; reusing an EOL constant list meant for CSV, which also permits a third value.
Common situations: Export settings UIs exposing free-text newline fields; shared newline constants between CSV and HTML writers where the CSV-legal lone CR leaks into the HTML writer.
Related errors
- Directory does not exist: $cacheDirectory
- Invalid value $calculateDateTimeType for calculated date tim
- Valid directory to TrueType Font files not specified
- Unknown font name "$name". Cannot map to TrueType font file
- Invalid timezone {$timezoneName}
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/32d0b864f44d16ab.
Report an issue: GitHub.