PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Calculation\Exception
Unsupported numeric binary operation
Error message
Unsupported numeric binary operation
What it means
Before doing any encoding detection, XmlScanner::findCharSet() checks whether the payload begins with the bytes \x4c\x6f\xa7\x94, which are '<?xm' in EBCDIC (code page 037/1027 family). An XML file that starts this way is an EBCDIC-encoded document, typically transferred straight from a mainframe; libxml cannot parse it and the scanner blocks it immediately with 'EBCDIC encoding not permitted' at XmlScanner.php:68.
Source
Thrown at src/PhpSpreadsheet/Calculation/Calculation.php:2660
case '/':
if ($operand2 == 0) {
// Trap for Divide by Zero error
$stack->push('Error', ExcelError::DIV0());
$this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails(ExcelError::DIV0()));
return false;
}
$result = $operand1 / $operand2;
break;
// Power
case '^':
$result = $operand1 ** $operand2;
break;
default:
throw new Exception('Unsupported numeric binary operation');
}
}
// Log the result details
$this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails($result));
// And push the result onto the stack
$stack->push('Value', $result);
return $result;
}
/**
* Trigger an error, but nicely, if need be.
*
* @return false
*/
protected function raiseFormulaError(string $errorMessage, int $code = 0, ?Throwable $exception = null): bool
{View on GitHub (pinned to 65b080eef4)
Solutions
- Convert the file from EBCDIC to UTF-8 before loading: iconv -f CP037 -t UTF-8 input.xml > input.utf8.xml (pick the CCSID that matches the source system).
- Re-transfer the file from the host in ASCII/text mode, or have the generating job emit ASCII/UTF-8 directly.
- If your pipeline routinely receives such files, add an upload gate that checks the first 4 bytes and auto-converts (or rejects) before the reader sees them.
- Confirm the correct EBCDIC code page (037 vs 1026 vs 500) by round-tripping a known snippet, since national characters differ between pages.
Example fix
// before
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load('mainframe-report.xml');
// throws: EBCDIC encoding not permitted (starts with \x4c\x6f\xa7\x94)
// after - convert EBCDIC (CP037) to UTF-8 before loading
$xml = file_get_contents('mainframe-report.xml');
if (str_starts_with($xml, "\x4c\x6f\xa7\x94")) {
$xml = mb_convert_encoding($xml, 'UTF-8', 'CP037');
}
$tmp = tempnam(sys_get_temp_dir(), 'xlsx');
file_put_contents($tmp, $xml);
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($tmp); Defensive patterns
Strategy: validation
Validate before calling
// Detect and (optionally) convert EBCDIC before loading
function normalizeEbcdic(string $path): string
{
$raw = (string) file_get_contents($path);
if (str_starts_with($raw, "\x4c\x6f\xa7\x94")) { // EBCDIC '<?xm'
$raw = mb_convert_encoding($raw, 'UTF-8', 'CP037'); // adjust CCSID if needed
}
return $raw;
}
$clean = normalizeEbcdic($path);
$tmp = tempnam(sys_get_temp_dir(), 'xlsx');
file_put_contents($tmp, $clean);
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($tmp); Try / catch
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
try {
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($path);
} catch (ReaderException $e) {
if (str_contains($e->getMessage(), 'EBCDIC')) {
// re-request the file in ASCII/UTF-8 from the source system, or convert via iconv -f CP037
}
throw $e;
} Prevention
- Configure mainframe/IBM i transfers to emit ASCII or UTF-8 (FTP ASCII mode, or CCSID conversion in the generating job).
- Check the first four bytes of inbound partner feeds (\x4c\x6f\xa7\x94) and convert before ingestion.
- Pin the correct EBCDIC code page in your conversion (037 vs 1026 vs 500) and verify national characters round-trip.
- Document expected encodings per upstream source so mismatches surface as pipeline errors, not reader exceptions.
When it happens
Trigger: Calling IOFactory::load() or scanFile() on a file that was encoded in EBCDIC (e.g. CCSID 037/500/1026 on z/OS or AS/400) and copied or FTP'd in binary mode without ASCII conversion. The first four bytes match the EBCDIC '<?xm' magic and the exception fires before BOM or declaration sniffing even runs.
Common situations: Feeds or reports generated on IBM mainframes (z/OS) or IBM i and transferred in binary; SFTP/managed-file-transfer pipelines that skip encoding translation; archives where the file was never converted after leaving the host system.
Related errors
- Unsupported binary comparison operator
- Cloning the calculation engine is not allowed!
- Locale file not found
- #VALUE!
- #NUM!
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/598daaa060e4f12b.
Report an issue: GitHub.