The Story of PHP 8.5.6 Release Candidate 3
Thursday, 30 April 2026I have previously had to skip a non-stable release (PHP 8.5.0 alpha3), and to create an extra unplanned release candidate (PHP 8.5.0 RC5). For PHP 8.5.6 release candidate 3, I had to do both: release candidate 2 was unplanned, and then an error led to skipping it, resulting in release candidate 3 that I just announced. Here is what happened.
Uriparser vulnerability
When PHP 8.5.6 RC1 was tagged and announced, it was expected to be the only release candidate. However, earlier this week a vulnerability (CVE-2026-42371) in the uriparser library was disclosed. That library is bundled with PHP 8.5.
On Monday, a pull request, #21890, was opened for PHP to update the bundled library to the latest version, where the vulnerability was fixed. Since the vulnerability was in an upstream dependency and had already been announced publicly, this security fix was performed in public on GitHub, rather than in private as described in PHP's security policy.
I merged that change, and cherry-picked it to the PHP-8.5.6 branch. So far, everything was relatively familiar - I had done something similar for the extra release candidate for PHP 8.5.0. Seeing no regression reports or other fixes that needed to be included in PHP 8.5.6, on Tuesday I proceeded to tag and build a second release candidate. Everything was going as expected; RC2 was unplanned, but I've had to deal with unexpected release candidates before.
ext/dom compilation
On Wednesday, before I had announced the second release candidate, a bug report
was filed on GitHub (#21911). On Windows only, when trying to build
the dom extension in shared mode (--with-dom=shared), compilation would fail.
The cause was a problematic upmerge from PHP-8.4 to PHP-8.5 when updating to a
newer version of the lexbor library. As a result of some internal
reorganization between PHP 8.4 and 8.5, the lexbor upgrade placed some
dependency files in incorrect locations in PHP 8.5.
Normally, when bugs are resolved the fixes go out in the next bugfix release that is not already in progress, meaning PHP 8.5.7 in this case. However, this was a bug that was introduced after PHP 8.5.5 was released - in other words, it would have been a regression between PHP 8.5.5 and 8.5.6. In those cases, if fixes are available in time they are included immediately. This is the whole reason we use release candidates: to catch regressions before they reach a stable release.
Since I had already tagged and built PHP 8.5.6RC2, this meant that a third release candidate was needed. I cherry-picked the fix and tagged and built a new release candidate, PHP 8.5.6RC3.
Looking ahead
For most patch releases (i.e. PHP 8.5.X) only a single release candidate is needed. Building three candidates is rare, but it happens (e.g. PHP 8.3.1RC3). Hopefully, no new issues are found and PHP 8.5.6 can be released as scheduled next week.