Composer "config.platform" Mismatch - Resolving Against the Wrong PHP
config.platform.php in composer.json pins the PHP version Composer resolves against, regardless of the real interpreter. When that pin drifts from the PHP actually running in CI, you get installs that assume the wrong version - too new to run, or too old to use needed features.
What this error means
Composer resolves and installs cleanly, but either the lockfile targets a PHP older/newer than the runner, or runtime fails on a feature the faked platform claimed. php -v and config.platform.php disagree.
// composer.json
"config": { "platform": { "php": "8.1.0" } }
$ php -v
PHP 8.3.4 (cli)
# Composer locks packages for 8.1, so an 8.3-only dependency is never selected,
# or a package capped at <8.2 is wrongly considered installable.Common causes
The pinned platform version is stale
config.platform.php was set to match an old deploy target and never updated. The solver honours the pin, not the real PHP, so the resolved set targets the wrong version.
Platform pin set higher than the runtime
If the pin claims a newer PHP than the runner has, Composer may select packages that the actual interpreter cannot run, failing at runtime rather than install.
How to fix it
Align config.platform.php with the deploy target
Set the pin to the lowest PHP your production actually runs, and keep CI on that version (or test a matrix).
{
"config": {
"platform": { "php": "8.3.0" }
}
}Inspect the effective platform
Ask Composer what platform it is resolving against versus the real interpreter.
composer config platform.php
php -v
composer check-platform-reqsRe-lock after changing the pin
A platform change affects resolution, so regenerate the lockfile.
composer update --lock
git add composer.json composer.lockHow to prevent it
- Set
config.platform.phpto your production PHP and review it on every PHP upgrade. - Run
composer check-platform-reqsin CI to catch drift. - Keep the CI PHP version aligned with the platform pin.