PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Reader\Exception

{filename} is an invalid Gnumeric file.

Error message

{filename} is an invalid Gnumeric file.

What it means

Gnumeric::listWorksheetInfo() validates the file with canRead() (gzip-compressed XML carrying the gnumeric namespace signature) before parsing sheet metadata. When the sniff fails, it throws this 'invalid Gnumeric file' exception before any XML is read.

Source

Thrown at src/PhpSpreadsheet/Reader/Gnumeric.php:168

            } elseif (self::matchXml($xml, 'Sheets')) {
                //    break out of the loop once we've got our sheet names rather than parse the entire file
                break;
            }
        }

        return $worksheetNames;
    }

    /**
     * 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
    {
        File::assertFile($filename);
        if (!$this->canRead($filename)) {
            throw new Exception($filename . ' is an invalid Gnumeric file.');
        }

        $xml = new XMLReader();
        $contents = $this->gzfileGetContents($filename);
        $xml->xml($contents);
        $xml->setParserProperty(2, true);

        $worksheetInfo = [];
        while ($xml->read()) {
            if (self::matchXml($xml, 'Sheet')) {
                $tmpInfo = [
                    'worksheetName' => '',
                    'lastColumnLetter' => 'A',
                    'lastColumnIndex' => 0,
                    'totalRows' => 0,
                    'totalColumns' => 0,
                    'sheetState' => Worksheet::SHEETSTATE_VISIBLE,
                ];

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Use IOFactory::identify($filename) to determine the real format and pick the matching reader
  2. Verify the file actually opens in Gnumeric/LibreOffice; re-export if corrupt
  3. For your own Gnumeric exports, validate canRead() right after writing as a smoke test

Example fix

// before
$info = (new Gnumeric())->listWorksheetInfo('upload.gnumeric'); // actually XML -> throws

// after
$type = IOFactory::identify('upload.gnumeric');
$reader = IOFactory::createReader($type);
$info = $reader->listWorksheetInfo('upload.gnumeric');
Defensive patterns

Strategy: validation

Validate before calling

$reader = new Gnumeric();
if (!$reader->canRead($filename)) {
    throw new RuntimeException('Not a readable Gnumeric file: ' . $filename);
}
$info = $reader->listWorksheetInfo($filename);

Prevention

When it happens

Trigger: Calling listWorksheetInfo() with a plain XML/xlsx/ods file that merely has a .gnumeric extension; a truncated or corrupt gzip stream; a Gnumeric file from a version whose signature the reader does not recognize.

Common situations: User uploads accepted by extension instead of content; downloads interrupted so the .gz payload is incomplete; mixed-format ingest pipelines.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/562711f8437c2dd2. Report an issue: GitHub.