PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Reader\Exception
{filename} is an Invalid SYLK file.
Error message
{filename} is an Invalid SYLK file. What it means
The SYLK (.slk) reader's canReadOrBust() requires the format's signature: a first record starting with ID;P plus recognizable delimiter lines. When canRead() fails it throws 'Invalid SYLK file' before parsing, so the content simply is not a Multiplan-style SYLK export.
Source
Thrown at src/PhpSpreadsheet/Reader/Slk.php:84
$data = (string) fread($this->fileHandle, 2048);
// Count delimiters in file
$delimiterCount = substr_count($data, ';');
$hasDelimiter = $delimiterCount > 0;
// Analyze first line looking for ID; signature
$lines = explode("\n", $data);
$hasId = str_starts_with($lines[0], 'ID;P');
fclose($this->fileHandle);
return $hasDelimiter && $hasId;
}
private function canReadOrBust(string $filename): void
{
if (!$this->canRead($filename)) {
throw new ReaderException($filename . ' is an Invalid SYLK file.');
}
$this->openFile($filename);
}
/**
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns).
*
* @return array<int, array{worksheetName: string, lastColumnLetter: string, lastColumnIndex: int, totalRows: int, totalColumns: int, sheetState: string}>
*/
public function listWorksheetInfo(string $filename): array
{
// Open file
$this->canReadOrBust($filename);
$fileHandle = $this->fileHandle;
rewind($fileHandle);
$worksheetInfo = [['worksheetName' => basename($filename, '.slk')]];
View on GitHub (pinned to 65b080eef4)
Solutions
- Use IOFactory::identify() to route the file to the right reader
- Open the file in Excel/LibreOffice and re-export as genuine SYLK (or better, CSV/xlsx)
- Sanity-check the first line: it should start with ID;P before you attempt the Slk reader
Example fix
// before
$spreadsheet = (new Slk())->load('export.slk'); // first line is not ID;P -> throws
// after
$first = (string) fgets(fopen($uploadPath, 'rb'));
if (!str_starts_with($first, 'ID;P')) {
$reader = IOFactory::createReader(IOFactory::identify($uploadPath));
$spreadsheet = $reader->load($uploadPath);
} else {
$spreadsheet = (new Slk())->load($uploadPath);
} Defensive patterns
Strategy: validation
Validate before calling
$firstLine = (string) fgets(fopen($filename, 'rb'));
if (!str_starts_with($firstLine, 'ID;P')) {
throw new RuntimeException('File lacks the SYLK ID;P signature');
}
$spreadsheet = (new Slk())->load($filename); Prevention
- Check the ID;P header before handing files to the Slk reader
- Use IOFactory::identify() for extension-untrusted uploads
- Re-export 'almost-SYLK' files from their source application as real SYLK or CSV
When it happens
Trigger: A .slk file whose first line is not ID;P (some tools emit data records or a preamble first); a plain text file renamed .slk; a SYLK variant using line endings/escapes the sniff does not recognize.
Common situations: Exports from niche ERP/lab tools that produce 'almost-SYLK' text; legacy .slk archives; user uploads validated by extension only.
Related errors
- $filename is an Invalid Spreadsheet file.
- {filename} is an invalid Gnumeric file.
- {filename} is an Invalid HTML file.
- XOr encryption not supported
- Cannot read this Excel file. Version is too old.
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/07fade9ab0db41e7.
Report an issue: GitHub.