
Inspect Composer’s configuration:
Version note: The examples use Drupal 11.4.11, a production-ready release available when this guide was reviewed on October 30, 2026. Check the supported releases before following the commands later. Read the Drupal 11.4.11 release notes (opens in a new tab).
Two files describe much of that arrangement:A homepage that loads is encouraging. It is not a complete acceptance test.Run commands from the directory containing composer.json, which is usually above Drupal’s web directory.Now imagine the module’s maintainers have released version 2 with Drupal 11 support. Composer still cannot select it while your project requires ^1.0.Work on a local or staging copy, with a separate Git branch and recoverable backups of the database and uploaded files.
1. Understand what Composer is trying to protect
Small differences in version constraints have significant consequences:An update must find a combination that satisfies the applicable requirements. If one package requires Drupal 10 while your project requests Drupal 11, Composer cannot satisfy both.
composer.jsondefines the packages your project requires and the versions it permits.composer.lockrecords the exact versions selected for installation.
Several paragraphs follow. Somewhere in that wall of text is the reason your afternoon has changed.Your project requires:
drupal/example_module ^1.0
That module's 1.x releases require:
drupal/core ^10
Your planned upgrade requires:
drupal/core ^11
For this documented dependency, configure the specific permission:
2. Prepare the site before changing dependencies
The solution starts with finding that requirement—not trying increasingly adventurous combinations of update flags.composer config allow-plugins.symfony/runtime true
Drupal 11.4 introduced Symfony Runtime into its bootstrap process. Its Composer plugin needs explicit permission to execute. Read Drupal’s Symfony Runtime change record (opens in a new tab).Once the update finishes, check the resulting project:For a typical drupal/recommended-project installation that already uses all three packages below, prepare the requirements:Finally, distinguish dependency resolution from installation failures. If Composer selects packages successfully but a patch fails to apply, investigate whether that patch is still needed or matches the new package version. Changing core constraints may have nothing to do with it.
3. Ask Composer which package blocks the upgrade
Deployment should reproduce that tested dependency set with composer install, using your established deployment options and workflow. Running a fresh composer update on production can select a different set of packages. See Composer’s guidance on installing from the lock file (opens in a new tab).Then test the journeys your users depend on:An unapproved plugin and an incompatible package are different problems. Read the error before treating them as the same issue.composer why vendor/package --tree
Also remember the distinction between two common commands: composer install reproduces the versions in an existing lock file; composer update resolves permitted versions and updates that file. See Composer’s basic usage documentation (opens in a new tab).Consider this fictional example:
4. Read a conflict as a chain of requirements
Use Upgrade Status to review contributed projects and custom code. A dependency solver cannot establish that your custom module’s PHP code will work with the new Drupal APIs. Upgrade Status helps identify those compatibility gaps. See the Upgrade Status project (opens in a new tab).Changing a version declaration alone does not make incompatible code compatible.For a Drupal 10-to-11 upgrade, Drupal documents 10.3.0 as the minimum starting version. That is an upgrade prerequisite, not a recommendation to remain on an old release. Bring the site to a currently supported Drupal 10 release first, and address core extensions removed in Drupal 11. Read Drupal’s major upgrade instructions (opens in a new tab).Do not use --ignore-platform-reqs to make an upgrade appear compatible. The application still needs the required PHP version and extensions when it runs.
- Read the module’s release notes and upgrade instructions.
- Confirm that its newer branch supports your target Drupal version.
- Change the project’s module constraint.
- Include that module in the planned update.
- Test its functionality and any required data updates.
composer validate
composer check-platform-reqs
composer audit
Expect to see the existing core requirements among the results when crossing major versions. Those must change, but look beyond them for modules, tools, and libraries that also restrict the target.
5. Check PHP and the environment Composer actually sees
Keep a rollback plan that accounts for database changes as well as code. Restoring older files alone may not reverse an upgrade.composer require
'drupal/core-dev:~11.4.11'
--dev --no-update
composer why-not drupal/core 11.4.11 --tree
You would need to:vendor/bin/drush updatedb
vendor/bin/drush cache:rebuild
Preview the core update:
6. Check version constraints before adding update flags
A frequent source of confusion is that the PHP running Composer can differ from the PHP serving the website. Composer also treats PHP extensions as platform dependencies; it cannot install a missing system extension as an ordinary PHP package. See Composer’s guide to platform dependencies (opens in a new tab).
| Constraint | Versions it permits |
|---|---|
^10 |
Drupal 10 releases, below Drupal 11 |
^11.4 |
Drupal 11.4 and later Drupal 11 releases, below Drupal 12 |
~11.4.11 |
Drupal 11.4.11 and later patches in the 11.4 series |
11.4.11 |
Exactly that release |
Do not treat security advisory blocks as ordinary version disagreements. Find a patched, compatible combination rather than disabling protection to finish the update.Update that setting only when the actual deployment environment is ready. Changing config.platform does not upgrade PHP on your server. See Composer’s platform configuration (opens in a new tab).Review changed scaffold files and release-specific instructions. For example, Drupal 11.4.11 includes an .htaccess change that site owners should check against their configuration. See the Drupal 11.4.11 release notes (opens in a new tab).Do not lower project-wide stability settings just to obtain one package. Investigate that package’s supported releases and maintenance status.composer require
'drupal/core-recommended:~11.4.11'
'drupal/core-composer-scaffold:~11.4.11'
'drupal/core-project-message:~11.4.11'
--no-update
For this walkthrough, ~11.4.11 keeps the update within Drupal 11.4 while allowing subsequent patches. Your project may intentionally use a broader range.For example, a PHP 8.2 platform setting can prevent resolution for Drupal 11 even when your local terminal runs PHP 8.3.composer update "drupal/core-*"
--with-all-dependencies --dry-run
The next time Composer blocks an update, start with the package name, its requirement, and the dependency chain. That turns an intimidating error into a concrete decision: update a module, adjust a constraint, fix the environment, or address incompatible code.
8. Preview the update, then apply it
What has blocked your Drupal upgrade: a contributed module, PHP requirements, Drush, or something unexpected? Share the package name and how you resolved it—your experience could help another Drupal team get unstuck.Do not delete composer.lock as your first troubleshooting step. Keep the known dependency state available for comparison.Think of the error as a disagreement between requirements. Your job is to find which requirement needs to change.Drupal 11 requires PHP 8.3 or later, alongside its other platform requirements. Check the requirements for your target release and hosting environment. See the Drupal 11 upgrade prerequisites (opens in a new tab).composer update "drupal/core-*" drush/drush
--with-all-dependencies --dry-run
composer prohibits drupal/core 11.4.11 --tree
If no compatible release exists, the decision becomes a project question: replace the module, remove it through Drupal’s proper uninstall process, contribute a compatibility fix, or postpone the upgrade.Work through one dependency chain at a time. The first visible blocker may not be the only one.The good news: a Composer conflict usually has an identifiable cause. A module needs an older Drupal version, a development tool restricts a shared dependency, or Composer sees a different PHP environment than you expected.If resolution still fails, return to the named blocker. Repeating -W more enthusiastically will not change what a package supports.A Drupal website contains more than Drupal core. It also depends on contributed modules, PHP libraries, development tools, and the platform running them.You have scheduled the upgrade, backed up the website, and opened your terminal. Then Composer delivers its familiar verdict:
10. Verify Drupal before calling the upgrade complete
Collect a baseline:Your requirements could not be resolved to an installable set of packages.These ranges follow Composer’s rules for versions and constraints (opens in a new tab).composer config --list --source
Commit the reviewed composer.json, composer.lock, and relevant project changes together.This guide covers Composer-managed Drupal projects upgrading from Drupal 10 to Drupal 11, as well as Drupal 11 sites struggling with an update.
- Sign-in and permissions.
- Content creation, editing, and publishing.
- Forms, email delivery, and file uploads.
- Search and important integrations.
- Checkout and payment flows, where applicable.
On your local or staging site, run database updates and rebuild caches:
11. Deploy the dependency set you tested
A temporary mismatch between composer.json and composer.lock is expected after preparing requirements with --no-update. The successful update should bring them back into agreement.Some apparent fixes make the terminal quieter while leaving the website harder to trust.Start with a specific target:php -v
composer --version
composer validate
composer diagnose
composer show drupal/core
composer show --direct
If you changed a module or Drush requirement, include that package explicitly in the update list. For a project with Drush installed:




