PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
File appears to be corrupt
Error message
File appears to be corrupt
What it means
getUInt2d() reads two bytes at a position confirmed against the data length; when the position is at/past the end of the loaded byte stream, confirmPos() throws 'File appears to be corrupt'. In practice the data ended earlier than the record structure promised.
Source
Thrown at src/PhpSpreadsheet/Reader/XlsBase.php:374
for ($i = 0; $i < $strLen; ++$i) {
$uncompressedString .= $string[$i] . "\0";
}
return $uncompressedString;
}
/**
* Convert string to UTF-8. Only used for BIFF5.
*/
protected function decodeCodepage(string $string): string
{
return StringHelper::convertEncoding($string, 'UTF-8', $this->codepage);
}
protected static function confirmPos(string $data, int $pos): void
{
if ($pos >= strlen($data)) {
throw new PhpSpreadsheetException('File appears to be corrupt'); // @codeCoverageIgnore
}
}
/**
* Read 16-bit unsigned integer.
*/
public static function getUInt2d(string $data, int $pos): int
{
self::confirmPos($data, $pos + 1);
return ord($data[$pos]) | (ord($data[$pos + 1]) << 8);
}
/**
* Read 16-bit signed integer.
*/
public static function getInt2d(string $data, int $pos): int
{View on GitHub (pinned to 65b080eef4)
Solutions
- Verify the transfer end-to-end: compare file size/checksum with the source and re-download
- Confirm the file opens in Excel; if Excel also complains, it is genuinely truncated
- Extract a fresh copy from the original archive or re-export from the source system
- Raise/verify upload_max_filesize and post_max_size and check for proxy limits if it came from HTTP upload
Defensive patterns
Strategy: validation
Validate before calling
if (!is_file($path) || filesize($path) === 0 || filesize($path) < 512) {
throw new InvalidArgumentException('File missing, empty, or truncated: ' . $path);
} Try / catch
try {
$spreadsheet = IOFactory::load($path);
} catch (\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
if (str_contains($e->getMessage(), 'File appears to be corrupt')) {
// likely truncated transfer: compare checksum with source and re-download
}
} Prevention
- Verify upload completeness (size + checksum) before parsing
- Check PHP upload limits and proxy timeouts on import endpoints
- Store originals immutably and re-copy when corruption is detected
When it happens
Trigger: A truncated .xls (interrupted upload/download, disk-full during write, partial archive extraction) where the reader walks records past EOF; files whose OLE workbook stream was cut short.
Common situations: User uploads cut off by PHP upload limits or proxy timeouts; files copied from failing media; spreadsheets embedded in PDFs/documents extracted incompletely.
Related errors
- unable to unpack data
- Unexpected file pass record length
- Unsupported encryption algorithm
- Decryption password incorrect
- Unrecognized space type in tAttrSpace token
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/746a1d0b77c6acbd.
Report an issue: GitHub.