We’re experiencing a recurring 500 error in the admin panel on PHP 8.1 and PHP 8.2, on several different pages (including payments.manage, but not limited to it — other admin pages trigger the same error).
Exact error message:
PHP Fatal error: ob_get_clean(): Cannot use output buffering in output buffering display handlers in app/Tygh/Ajax.php on line 146
Context:
CS-Cart version: 4.19 SP1
Tested on PHP 7.4: works perfectly, no issues
Tested on PHP 8.1: some pages work, others crash with this error (500, blank page)
Tested on PHP 8.2: same behavior, error occurs right away on payments.manage
We are currently back on PHP 7.4 to keep the site operational
Checks already done server-side:
zlib.output_compression is disabled in php.ini (so not the cause)
Required PHP extensions verified and present
Given that your documentation states PHP 8.1 has been supported since 4.17.1 and PHP 8.2 since 4.18.1, our version should be well within the compatible range. Could you help us identify the cause of this conflict? Is it related to a third-party add-on, a missing patch for 4.19 SP1, or a known bug?
That callback only fires when the request ended without destructors being run. An uncaught error or a normal exit still runs __destruct(), and then you get the real message. What skips destructors is memory_limit exhausted and max_execution_time exceeded.
With a timeout, the error log has “Maximum execution time of N seconds exceeded” directly above the ob_get_clean line. With memory exhaustion, the “Allowed memory size … exhausted” line never reaches the error log at all, so the ob_get_clean fatal is the only thing you see.
So, check the line directly above in the PHP error log. If there is one, thats your actual error. If ob_get_clean stands there alone, look at memory first: check the effective memory_limit of the PHP 8.1/8.2 pool via phpinfo() in the browser, not the CLI value. Moving to a new PHP version usually means a new FPM pool with the default 128M. Try 512M and see if payments.manage starts working.
The buffer is only started for internal ajax requests (Ajax::isInternalRequest(), line 426). Open the same dispatch directly in the browser, without is_ajax, and the handler is skipped so the original error shows up.
Just wanted to say thank you — your diagnosis was exactly right and got us to the actual fix.
The ob_get_clean() message was indeed just a downstream symptom. Following your suggestion, we opened the failing dispatch directly in the browser (bypassing the internal AJAX request/buffer) and also re-enabled log_errors, which had been switched off in the PHP INI settings and was hiding the real error.
That surfaced the true fatal error:
“Array and string offset access syntax with curly braces is no longer supported”
It was coming from a few third-party addons using an obfuscated/protected code loader that still relied on old curly-brace string/array offset syntax, removed in PHP 8.0. We found three affected modules from the same vendor, disabled all three, and the admin now runs cleanly on PHP 8.1.
Really appreciate you pointing us in the right direction instead of just the visible error message — saved us a lot of time.