You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
"OpenSslCipherMethodsProvider" Emits Warnings on PHP 8.4 / OpenSSL 3 #15176
"openssl_get_cipher_methods(true)" reports ciphers that "openssl_cipher_iv_length()" rejects, such as "aes-128-cbc-cts". PHPStan 2.2.13 probes these methods when computing result-cache metadata, causing warnings.
Not sure it's because I run different php versions in WSL vs. Docker or something like that and the result cache struggle with it?
Code snippet that reproduces the problem
No response
Expected output
No php warning from internal phpstan code.
Did PHPStan help you today? Did it make you happy in any way?
My coding agents like to run PHPStan to fix their sloppy code. 😅
This bug report is missing a link to reproduction at phpstan.org/try.
It will most likely be closed after manual review.
The warning originates while PHPStan builds its own result-cache metadata in "OpenSslCipherMethodsProvider", so I don't think a PHPStan playground link can reproduce this reliably, because the relevant input is the runtime OpenSSL cipher set and PHP error-handler configuration rather than the analysed source.
What produces it: openssl_get_cipher_methods() reports algorithms openssl_cipher_iv_length() rejects on PHP 8.0-8.4 (php/php-src#19994), so the provider filters them out by probing each one, and every rejection warns. On PHP 8.4.23 with OpenSSL 3.6.3 that is 40 of 248, aes-128-cbc-cts among them. On PHP 8.5 nothing is rejected, which is why most people never see it.
@staabm is right that the call is @-suppressed and that this normally hides it. The gap is that @ does not stop a user error handler which does not consult error_reporting(): such a handler is still called for a suppressed diagnostic. PHPStan's own handlers do check the mask, so they never reported these.
I have not been able to pin down what does it in your setup, and I would rather say that than guess. Two things I tried:
installing exactly such a handler from a bootstrapFiles entry does not surface the warnings in a real run here. The handler is demonstrably active (it sees a suppressed trigger_error() at bootstrap time) yet it is invoked zero times across a whole analysis, while the probe definitely runs, since its hash lands in the cache file. So something between bootstrap and the probe holds a handler that does respect the mask.
xdebug.scream=1 disables @ outright and is documented to have this effect, but Xdebug is not loaded on this machine, so I could not confirm it.
So if you can say a bit more, it would help: is Xdebug loaded with scream on, and do you invoke PHPStan through a wrapper script or anything else that installs an error handler before it runs? Your PHP 8.4 plus OpenSSL 3 is the part I have reproduced.
Either way we should not be provoking it, so the fix does not depend on the answer: it puts a handler of ours on top of the stack for the duration of the probe, which swallows the warning whoever else is listening, and restores yours afterwards. Measured on PHP 8.4.23 with a mask-ignoring handler installed: 40 warnings before, 0 after, and the computed hash is byte-identical, so your cache is not invalidated by the change.
On your other question, whether this is about running different PHP versions in WSL and Docker: not the warning, but your instinct about the result cache is right, and it is why this provider exists. The supported cipher set is a property of the build rather than of the PHP version, so two environments at the same PHP_VERSION_ID can report different sets, and the inferred type of openssl_cipher_iv_length() follows. That set is in the cache key exactly so a cache from one is not reused in the other. If your WSL and Docker images carry different OpenSSL builds, a full re-analysis when you switch is expected, and that part is deliberate.
Activity
mergeable commentedon Sep 4, 2026
This bug report is missing a link to reproduction at phpstan.org/try.
It will most likely be closed after manual review.
voku commentedon Sep 4, 2026
The warning originates while PHPStan builds its own result-cache metadata in "OpenSslCipherMethodsProvider", so I don't think a PHPStan playground link can reproduce this reliably, because the relevant input is the runtime OpenSSL cipher set and PHP error-handler configuration rather than the analysed source.
staabm commentedon Sep 4, 2026
//cc @SanderMuller
staabm commentedon Sep 4, 2026
@voku do you use some kind of custom error handler when running PHPStan?
the call in question is actually prefixed with a error-suppression operator, which should hide such warnings..?
a error handling which does not respect the
@could lead to such warning and should be fixed itself.SanderMuller commentedon Sep 4, 2026
That provider is mine, sorry for the noise. Fix attempt in: phpstan/phpstan-src#6372.
What produces it:
openssl_get_cipher_methods()reports algorithmsopenssl_cipher_iv_length()rejects on PHP 8.0-8.4 (php/php-src#19994), so the provider filters them out by probing each one, and every rejection warns. On PHP 8.4.23 with OpenSSL 3.6.3 that is 40 of 248,aes-128-cbc-ctsamong them. On PHP 8.5 nothing is rejected, which is why most people never see it.@staabm is right that the call is
@-suppressed and that this normally hides it. The gap is that@does not stop a user error handler which does not consulterror_reporting(): such a handler is still called for a suppressed diagnostic. PHPStan's own handlers do check the mask, so they never reported these.I have not been able to pin down what does it in your setup, and I would rather say that than guess. Two things I tried:
bootstrapFilesentry does not surface the warnings in a real run here. The handler is demonstrably active (it sees a suppressedtrigger_error()at bootstrap time) yet it is invoked zero times across a whole analysis, while the probe definitely runs, since its hash lands in the cache file. So something between bootstrap and the probe holds a handler that does respect the mask.xdebug.scream=1disables@outright and is documented to have this effect, but Xdebug is not loaded on this machine, so I could not confirm it.So if you can say a bit more, it would help: is Xdebug loaded with
screamon, and do you invoke PHPStan through a wrapper script or anything else that installs an error handler before it runs? Your PHP 8.4 plus OpenSSL 3 is the part I have reproduced.Either way we should not be provoking it, so the fix does not depend on the answer: it puts a handler of ours on top of the stack for the duration of the probe, which swallows the warning whoever else is listening, and restores yours afterwards. Measured on PHP 8.4.23 with a mask-ignoring handler installed: 40 warnings before, 0 after, and the computed hash is byte-identical, so your cache is not invalidated by the change.
On your other question, whether this is about running different PHP versions in WSL and Docker: not the warning, but your instinct about the result cache is right, and it is why this provider exists. The supported cipher set is a property of the build rather than of the PHP version, so two environments at the same
PHP_VERSION_IDcan report different sets, and the inferred type ofopenssl_cipher_iv_length()follows. That set is in the cache key exactly so a cache from one is not reused in the other. If your WSL and Docker images carry different OpenSSL builds, a full re-analysis when you switch is expected, and that part is deliberate.