PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Reader\Exception
Only Little-Endian encoding is supported.
Error message
Only Little-Endian encoding is supported.
What it means
Thrown by Shared\OLE::read() when the 2-byte field at offset 28 of the compound document is not the expected byte-order marker FE FF. The OLE2 spec defines only little-endian encoding, so a well-formed big-endian file is essentially nonexistent; in practice this exception marks a malformed or damaged header.
Source
Thrown at src/PhpSpreadsheet/Shared/OLE.php:126
*
* @return bool true on success, PEAR_Error on failure
*/
public function read(string $filename): bool
{
$fh = @fopen($filename, 'rb');
if ($fh === false) {
throw new ReaderException("Can't open file $filename");
}
$this->_file_handle = $fh;
$signature = fread($fh, 8);
if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) {
throw new ReaderException("File doesn't seem to be an OLE container.");
}
fseek($fh, 28);
if (fread($fh, 2) != "\xFE\xFF") {
// This shouldn't be a problem in practice
throw new ReaderException('Only Little-Endian encoding is supported.');
}
// Size of blocks and short blocks in bytes
/** @var int<1, max> */
$temp = 2 ** self::readInt2($fh);
$this->bigBlockSize = $temp;
$this->smallBlockSize = 2 ** self::readInt2($fh);
// Skip UID, revision number and version number
fseek($fh, 44);
// Number of blocks in Big Block Allocation Table
$bbatBlockCount = self::readInt4($fh);
// Root chain 1st block
$directoryFirstBlockId = self::readInt4($fh);
// Skip unused bytes
fseek($fh, 56);
// Streams shorter than this are stored using small blocksView on GitHub (pinned to 65b080eef4)
Solutions
- Treat it as corruption: re-obtain the file from its source and retry; compare checksums if available.
- Validate the file with another tool first (e.g. 'file report.xls', or opening in LibreOffice) to confirm the container is damaged.
- Parse defensively: wrap legacy .xls parsing in try/catch and surface a 'corrupt file' message rather than a library stack trace.
- If you accept untrusted uploads, reject files that fail signature+header validation early instead of parsing them.
Example fix
// before
try {
$ole->read('invoice.xls');
} catch (ReaderException $e) { /* generic */ }
// after
try {
$ole->read('invoice.xls');
} catch (ReaderException $e) {
if (str_contains($e->getMessage(), 'Only Little-Endian')) {
// header corruption — ask the sender for a fresh export
unlink('invoice.xls');
throw new RuntimeException('The .xls file is damaged. Please re-export it.', 0, $e);
}
throw $e;
} Defensive patterns
Strategy: try-catch
Validate before calling
$head = (string) @file_get_contents($file, false, null, 28, 2);
if ($head !== "\xFE\xFF") { /* header damaged — reject before OLE parsing */ } Try / catch
try { $ole->read($file); }
catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
if (str_contains($e->getMessage(), 'Little-Endian')) {
throw new RuntimeException('Workbook container is damaged — please re-export.', 0, $e);
}
throw $e;
} Prevention
- Treat this exception as proof of corruption; there is no big-endian OLE variant to support in practice.
- Verify transfers with checksums when .xls files move between systems.
- Validate the full header (signature + byte-order marker) before deeper parsing of untrusted files.
When it happens
Trigger: A file that passed the 8-byte OLE signature but whose header bytes at offset 28-29 differ — typically random corruption, a file that begins with a coincidental OLE signature, or a truncated/patched container. Reached only after the signature check in OLE::read(), so it implies the file at least looks like an OLE document at byte 0.
Common situations: Bit-level corruption from bad transfers or disk faults; deliberately crafted files (fuzzing payloads) whose header is nonsense; files produced by broken non-Microsoft writers that emit partial OLE headers.
Related errors
- Unsupported PPS type
- File doesn't seem to be an OLE container.
- Unable to open stream $path
- Expecting 8 byte string
- The filename $filename is not recognised as an OLE file
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/0452fc7cb371a48b.
Report an issue: GitHub.