PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Writer\Exception
$bitmap doesn't contain enough data.\n
Error message
$bitmap doesn't contain enough data.\n
What it means
After slurping the file into memory, processBitmap() rejects anything of 54 bytes (0x36) or fewer - smaller than a minimal BMP file header plus info header. This guards the subsequent offset-based unpack() calls from reading garbage. It catches truncated files and placeholder stubs; 0-byte files were already rejected by the previous check.
Source
Thrown at src/PhpSpreadsheet/Writer/Xls/Worksheet.php:2473
*
* @return array{0: int, 1: int, 2: int, 3: string} Data and properties of the bitmap
*
* @codeCoverageIgnore
*/
public function processBitmap(string $bitmap): array
{
// Open file.
$bmp_fd = @fopen($bitmap, 'rb');
if ($bmp_fd === false || 0 === (int) filesize($bitmap)) {
throw new WriterException("Couldn't import $bitmap");
}
// Slurp the file into a string.
$data = (string) fread($bmp_fd, (int) filesize($bitmap));
// Check that the file is big enough to be a bitmap.
if (strlen($data) <= 0x36) {
throw new WriterException("$bitmap doesn't contain enough data.\n");
}
// The first 2 bytes are used to identify the bitmap.
$identity = unpack('A2ident', $data);
if ($identity === false || $identity['ident'] != 'BM') {
throw new WriterException("$bitmap doesn't appear to be a valid bitmap image.\n");
}
// Remove bitmap data: ID.
$data = substr($data, 2);
// Read and remove the bitmap size. This is more reliable than reading
// the data size at offset 0x22.
//
$size_array = unpack('Vsa', substr($data, 0, 4)) ?: [];
/** @var int */
$size = $size_array['sa'];View on GitHub (pinned to 65b080eef4)
Solutions
- Re-download or re-export the original BMP
- Verify integrity (size and hash) before calling insertBitmap()
- Convert to PNG/JPEG and use the Drawing API instead of raw Xls bitmaps
Defensive patterns
Strategy: validation
Validate before calling
const MIN_BMP_SIZE = 54; // 0x36: file header (14) + info header (40)
if (!is_file($path) || filesize($path) < MIN_BMP_SIZE) {
throw new InvalidArgumentException("File too small to be a BMP: $path");
}
$worksheetWriter->insertBitmap($row, $col, $path); Try / catch
try {
$worksheetWriter->insertBitmap($row, $col, $path);
} catch (\PhpOffice\PhpSpreadsheet\Writer\Exception $e) {
if (str_contains($e->getMessage(), 'contain enough data')) {
error_log("Truncated bitmap rejected: $path"); // re-fetch source image
}
} Prevention
- Verify downloads completed (size and hash) before using files
- Validate uploaded images with getimagesize(), which fails on truncated files
- Keep original sources so truncated artifacts can be regenerated
When it happens
Trigger: A BMP file truncated below 54 bytes (interrupted download), a text/HTML error page saved with a .bmp extension, or a 1-53 byte stub passed to insertBitmap().
Common situations: Interrupted uploads/downloads; proxies or antivirus replacing the file body; unit-test fixtures that are empty shells.
Related errors
- Couldn't import $bitmap
- $bitmap isn't a 24bit true color bitmap.\n
- $bitmap: compression not supported in bitmap image.\n
- $bitmap doesn't appear to be a valid bitmap image.\n
- $bitmap: largest image width supported is 65k.\n
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/0611f28b4212bf41.
Report an issue: GitHub.