Drupal upgrade readiness audit: what it checks before you move to Drupal 11 or 12
A Drupal upgrade readiness audit inventories the hosting, custom code and contributed modules of a site, then turns those findings into an effort estimate that a steering group can approve. It answers two questions before any upgrade work is scheduled: which path applies to this site, and what has to change first. For a site that must move to a newer major version under a fixed date, the audit is the step that shows whether that date is realistic before anyone commits to it. The first decision is the path. Drupal 6 and Drupal 7 sites cannot be updated in place to Drupal 10 or later. Drupal.org documents that they are migrated into a new site with the core Migrate, Migrate Drupal and Migrate Drupal UI modules or with Drush, and that themes must be rebuilt because they cannot be migrated. The audit therefore records the current core version early, so the team knows whether it is planning an in-place upgrade or a migration project.
For sites already on Drupal 10 or 11, the audit checks the supported path against the Drupal core release schedule. That schedule lists Drupal 10 end of life on December 9, 2026 and Drupal 12 for the week of December 7, 2026. The audit should confirm the current support status of each version in use and the planned sequence of intermediate steps. It should also confirm the PHP minimums on the Drupal.org PHP requirements page: PHP 8.1 for Drupal 10, PHP 8.3 for Drupal 11 and PHP 8.5 for Drupal 12. Any server running an older PHP release is a gating item, so the hosting review belongs in the same audit as the code review.
Which Drupal release changes affect the upgrade and what to do about each
This table lists the Drupal release dates, PHP requirements and migration rules that shape an upgrade audit, with the impact of each on your site and the action to take. Read it as a checklist: confirm the dates against your own support plan, then assign an owner to each action before the audit begins.
| Release change | Impact on the site | Action needed |
|---|---|---|
| Drupal 10 end of life on December 9, 2026 | Security releases for Drupal 10 stop on that date, so sites still on Drupal 10 carry unpatched exposure afterward. | Record the end-of-life date in your change calendar and confirm the target version and go-live window with stakeholders. |
| Drupal 12 scheduled for the week of December 7, 2026 | Contributed modules and custom code must be checked against Drupal 12 before the release arrives, not after. | Run Upgrade Status against the current codebase now and list every module that lacks a Drupal 12 compatible release. |
| Drupal 10 requires PHP 8.1 or later | Servers still on older PHP versions cannot run Drupal 10, so the server layer can block the code upgrade. | Check the PHP version on each web and CLI server, including cron and queue workers, and record any gap. |
| Drupal 11 requires PHP 8.3 or later | Hosts on PHP 8.1 or 8.2 need an upgrade before Drupal 11 can be installed or tested. | Confirm that staging and production both run PHP 8.3 or later and that custom code passes tests on that version. |
| Drupal 12 requires PHP 8.5 or later | Sites that plan to skip straight to Drupal 12 need PHP 8.5 in every environment, and older hosts may need replacing. | Ask your hosting provider for a dated PHP 8.5 plan and include the server work in the audit scope. |
| No supported Drupal version runs on PHP 7 | Any site still on PHP 7 is outside what Drupal supports for current core versions. | Treat PHP 7 hosts as a priority finding and schedule the server upgrade before any Drupal code work. |
| Drupal 7 security support ended on January 5, 2025 | Drupal 7 sites no longer receive community security releases, so they need a migration plan or a paid extended support arrangement. | Plan a migration project to a supported Drupal version, or review the extended security support providers listed on Drupal.org if migration must wait. |
| Drupal 6 and 7 sites are migrated, not updated, and themes must be rebuilt | The upgrade becomes a new site build with content migration, so an in-place audit tool cannot measure the full effort. | Inventory content types, custom modules and themes, then scope the migration and theme rebuild separately from the readiness audit. |
What a Drupal upgrade readiness audit inspects
A readiness audit checks the platform, the code you own, the contributed code you depend on, the data, the connected systems and the recovery path before any upgrade work starts. The areas are linked: a blocker in one, such as a contributed module with no compatible release, changes the sequence and effort in the others.
Hosting and runtime
The auditor records the web server, the PHP version, and the database engine and version, then compares them with the target Drupal release. Confirm the PHP version first, because Drupal 11 and Drupal 12 each require a newer PHP than Drupal 10 does. Check whether the server and database upgrades can be scheduled with the code change, and whether the current hosts still receive operating system and PHP security updates.
Custom modules and themes
Upgrade Status scans custom code and reports deprecated APIs, removed functions and changed hooks, with each finding tied to a file and line. Drupal Rector then applies automated fixes for the patterns it knows. The auditor sorts the findings into automated, manual and redesign work, because custom code often needs decisions that no script can make, such as replacing a removed core feature.
Contributed modules and compatibility
For each contributed project, the auditor checks whether a release supports the target Drupal version, whether the project is maintained, and whether a security advisory is open. Upgrade Status also flags deprecated calls inside contributed code. Projects with no compatible release become named blockers with an owner, a replacement option or a patch plan. Record the decision for each one, not only the list.
Configuration and content data
The auditor reviews the exported configuration, content types, fields, views, text formats and the editorial workflow, then checks for settings that depend on a module or theme being removed from core. Content is sampled and checked for entity types, field storage and media references that a migration or update could break. Confirm that the configuration export is clean and committed to version control before the audit starts.
Integrations and authentication
The auditor lists every system Drupal talks to, including identity providers, CRMs, search engines, payment services and API clients, and records the module, version and credentials used for each. Authentication paths such as SSO, SAML and OAuth clients are tested against the target version, because a login break is one of the most visible failures after an upgrade. Confirm who owns each external connection.
Backup and test environment
The audit confirms that a recent, restorable backup of the database and files exists and that a test environment matches production closely enough to rehearse the upgrade. It also records the deployment path, the rollback plan and who signs off each stage. Without a working test copy, the readiness findings cannot be verified, so the effort estimate depends on this area as much as on the code scan.
Reading Upgrade Status and Drupal Rector output without overcounting
The first thing to understand about Upgrade Status output is that it lists every location where code uses a deprecated or removed API, and a raw count of those locations overstates the work. A single deprecated function called from forty places in one custom module is one change to make, not forty independent decisions. Before you put a number on the audit, sort findings into two groups: those that Drupal Rector can rewrite mechanically and those where a developer must decide what the new behavior should be. Rector handles renamed functions, moved classes and simple signature changes well. It does not decide what a deprecated hook should now do, how a changed service behaves, or whether a removed feature should be replaced with a contributed module or rebuilt. Run Rector on a branch, review the diff, and count only the findings it leaves behind as developer work.
Contributed modules need a separate rule. A deprecation inside a contributed module that has no release compatible with the target version is not a code fix you can make in your own repository. Your options are to wait for a maintainer release, to contribute a patch, to replace the module, or to carry a patched fork that you will maintain indefinitely. Record each such module with its current release, its target-version status on Drupal.org, and the decision taken. Treat a deprecation in an abandoned module as a replacement decision with its own estimate, not as a line in the custom-code total. Confirm the current compatibility status of each module on its project page, because it changes as maintainers release.
Because the report lists locations, the audit has to group findings by module and by owner before it produces an effort estimate. Group by the custom module or theme that contains the code, then by the team or vendor responsible for it, since the person who can approve a behavior change is often not the person who wrote the code. Check the tools' own documentation before the audit starts for the current behavior of Upgrade Status and Drupal Rector, the Drupal versions each one targets, and any known false positives. Versions and rules change between releases, so do not reuse results from an earlier scan without rerunning it against the target version you have chosen.
Hosting checks that can block the upgrade
Drupal runs on Apache, Nginx and other web servers, so the audit does not require one specific server. What it verifies is that the server version, its modules and its configuration support the target Drupal release and the PHP version that release needs. The audit reviews rewrite rules, the document root, upload size limits, timeouts and HTTPS settings, because these often break during a core upgrade even when the code is clean.
- Server version support: Confirm that the Apache or Nginx version in use is still receiving vendor updates and works with the PHP handler you plan to run.
- Rewrite and routing rules: Check that clean URLs, the front controller and private file paths match the configuration Drupal's current documentation expects.
- Request and upload limits: Compare body size, timeout and upload limits with what content editors and the media modules actually use.
- Document root and file access: Confirm that only the web root is exposed and that
settings.phpand private directories are not served. - Other servers: If your platform uses a different web server, confirm it with the platform vendor against the system requirements page.
Ask your hosting or platform team to confirm the exact server build, the PHP handler and any reverse proxy in front of Drupal, because the audit can only test what it is given.
Drupal supports MariaDB, MySQL, PostgreSQL and SQLite. The audit checks the engine, its version and its settings against the minimums listed for the target Drupal release, and it confirms the character set and collation that the existing site already uses. SQLite is usually suitable only for small or development sites, so a production site on SQLite should be reviewed as a separate decision.
- Engine and version: Record the exact database engine and version in production, staging and any replica, and compare each one with the target release's minimum.
- Character set and collation: Confirm that the database and tables use the encoding Drupal expects so that content migrates without corruption.
- Storage and backup format: Check that dumps and restore procedures work on the target version, since a restore test is the only proof a backup is usable.
- Database user privileges: Confirm that the account used during the upgrade can run schema updates, which often need more rights than daily operation.
- Exact minimums: Confirm the database minimums for your target release with the current Drupal.org system requirements page, as minimums change between releases.
The audit output should list each database version in use next to the minimum you confirmed, so the platform team can plan any database upgrade before the code upgrade.
PHP is usually the first hard gate. Drupal.org's PHP requirements page sets a minimum for each major release, and the audit compares the running PHP version, the extensions loaded and the php.ini settings against that minimum. Because no supported Drupal version runs on PHP 7, a site still on PHP 7 must change runtime before it can upgrade the core.
- Running version: Check the PHP version that web and command-line processes use, since they can differ on the same host.
- Extensions and modules: List loaded extensions and compare them with the Drupal and contributed module requirements, including any image, XML or database drivers.
- Memory and execution limits: Review
memory_limit,max_execution_timeandupload_max_filesizeagainst the update and cron workloads. - Opcode cache and configuration: Confirm that OPcache settings and configuration files are the same on every node.
- Vendor support for the target PHP version: Ask your operating system or platform vendor whether it supports the target PHP version, because a runtime that Drupal accepts may still be unsupported by your distribution.
Before approving the upgrade plan, get written confirmation of the PHP version and extensions on every environment, including the build pipeline.
What makes the audit and the upgrade take longer
This table compares the factors that move audit and upgrade effort on a Drupal site, why each one raises the work, and what to request in a written quote. Use it to see which drivers apply to your estate before you compare proposals, since the same site size can produce very different effort depending on these factors.
| Driver | Why it raises effort | What to ask for in a quote |
|---|---|---|
| Count and age of custom modules and themes | Every custom module and theme must be scanned, read and often rewritten. Older code usually relies on APIs that changed across several core releases. | Itemized inventory of custom modules and themes with last-modified dates, and the audit scope for each |
| Deprecated API use in custom code | Upgrade Status reports deprecations, and Drupal Rector fixes many of them automatically. Remaining findings need developer review and tests. | Count of findings by severity, the share expected to be fixed by Drupal Rector, and who reviews the manual changes |
| Contributed modules without a compatible release | A module with no release for the target version needs a replacement, a fork or a patch, and each option adds decisions and testing. | A per-module list showing current version, target version compatibility and the planned replacement or patch |
| Drupal 6 or 7 origins | Sites from these branches cannot be updated in place. Content and configuration must be migrated into a new site, and themes must be rebuilt. | Whether migration scope, theme rebuild and content mapping are included or priced separately |
| Multisite layouts | Each site in a shared codebase has its own modules, configuration and content, so findings and test runs multiply. | Number of sites, shared versus site-specific modules, and whether each site is tested separately |
| Identity provider and CRM integrations | Authentication, user sync and CRM connectors depend on contributed modules and external services that must be retested against the new version. | List of integrations, the modules used, and the test accounts and sandbox access the provider needs |
| Custom data and content volume | Large content sets, custom entities and complex field structures lengthen migration rehearsals and data validation. | Content counts by type, custom entity definitions and the validation method agreed for sign-off |
| Environments kept in step | Development, staging and production must receive the same code, configuration and database state, and each extra environment adds deployment and drift checks. | Environment list, the deployment method used (for example, Composer-based builds), and who owns each environment |
Audit steps, checkpoints and rollback points
The sequence moves from a frozen copy of the site to a decision review, with a named check and artifact at each stage. Production stays unchanged throughout, and every fix found along the way waits in a separate, reviewed branch.
Freeze a copy of production code and database
Record the exact production state before anything else happens. Export the Git commit or Composer lock file, the active configuration, and a database dump, then copy the public files directory. The check is that a fresh copy can be built and loaded in a non-production environment without changing production. The artifact is a snapshot record that lists the commit hash, lock file checksum and dump file name, so every later finding can be traced to a known state.
Take and verify a backup
Create a full backup of the frozen copy, covering the database, the files directory and the code repository, and store it outside the production environment. Restore it into a separate environment and confirm the site loads, that log-in works and that the content counts match the source. Do not start scanning until the restore succeeds. The artifact is a restore test record. It also gives you a rollback point if the audit environment is later changed by mistake.
Run the environment and component inventory
Build a list of everything the site depends on: the Drupal core version, PHP version, database engine and version, web server, every contributed module and theme with its release, and every custom module and theme with its owner. Confirm the current versions against the hosting requirements for the target Drupal version. The check is that the inventory matches the composer.lock file and the live modules page of the restored copy. The artifact is the inventory list, which becomes the baseline for all later steps.
Run Upgrade Status and Drupal Rector on the copy
On the restored copy only, run Upgrade Status against the target core version to scan custom code, contributed projects and the theme layer. Run Drupal Rector in dry-run mode so proposed changes are written to a report without touching files. The check is that both tools complete on every custom module and theme in the inventory. The artifacts are raw scan reports, which should be saved with the commit hash from the snapshot so the scan can be repeated.
Classify findings into a findings register
Sort each finding into categories such as hosting blocker, removed core feature, deprecated API in custom code, deprecated API in contributed code, and cosmetic. For each entry, record the file or project, the reported issue, whether Rector can fix it automatically, and a named owner. Review the register with the development lead to confirm no blocker has been filed as cosmetic. The check is that every scan result has one classification. The artifact is the findings register, the main working document for the rest of the audit.
Build the contributed module compatibility list
For each contributed project in the inventory, check its Drupal.org page for a release that supports the target core version, note any alpha, beta or dev status, and confirm whether a maintainer has announced a plan. Mark projects with no compatible release as blockers, and record a replacement or fork option for each. The check is that every contributed project has a status. The artifact is the compatibility list, which sets the critical path for the effort estimate.
Draft the effort estimate from the findings
Group the findings register and the compatibility list into work packages: automated fixes, manual code changes, contributed module replacements, hosting changes, and testing. For each package, record the drivers that raise or lower effort, such as the number of custom components, the depth of theme overrides and the number of integrations. Ask for written quotes that show these components separately. The check is that every blocker has a work package and an owner. The artifact is a draft estimate with stated assumptions, which can be reviewed by the decision group.
Hold the decision review and confirm fixes go to a branch
Present the inventory, findings register, compatibility list and draft estimate to the owners who will approve the upgrade. Decide which blockers must be resolved first, whether the work is done in-house or by a partner, and which fixes proceed. Any change identified during the audit is implemented in a separate branch, reviewed and tested in a copy, and merged only after approval. The check is a signed decision record. The artifact is that record plus the approved branch plan, and the audit itself makes no changes to production.
What the effort estimate contains and what it leaves open
A written effort estimate for a Drupal upgrade readiness audit should break the work into the parts that carry cost: findings grouped by category, the fix work for custom code, the work to replace or update contributed modules, infrastructure changes, testing and a rollback plan. Each finding from Upgrade Status and Drupal Rector should map to one of these categories, so the reader can see which deprecated API calls in custom modules and themes are cheap to fix automatically and which need a developer. Contributed modules without a compatible release need their own line, because the choice is between waiting for a maintainer, switching to another module, or writing a replacement. Ask for the estimate to name the PHP and database changes separately, since those often move on a different schedule from the code. A rollback plan should name the backup, the restore steps and who signs off on each.
The one-time cost is the upgrade itself: the audit, the code and module changes, the infrastructure work to meet the target PHP version, testing and cutover. Recurring cost begins after the site runs on the new version and includes security and bugfix updates, the next release cycle and the maintenance of any custom code that still depends on contributed projects. Ask the partner to state which items are one-time and which carry forward into a support arrangement, and to confirm the release window they assumed. The Drupal core release schedule is the reference for the dates that drive that recurring work.
Some effort cannot be known until the team runs a copy of the production site through the upgrade. Hidden deprecations in code paths that tests do not reach, module behavior that changes under real data, and performance differences on the target PHP version only appear in a test build. A fixed-scope agreement should record these as named open items with an owner, an agreed check and a decision point, rather than as a silent contingency. Ask how the agreement treats an open item that turns out larger than expected, and which changes need your written approval before work continues. Confirm also whether the estimate includes a second test cycle, since regulated change control often requires one.
Questions buyers ask before commissioning a Drupal upgrade readiness audit
How much does a Drupal upgrade readiness audit cost?
The price is set by the written scope, not by a list price. DeployOpen does not publish a price list, so a quote follows from the scope you agree in writing. The main cost drivers are the size of the site, the volume of custom code in your modules and themes, the number of contributed modules that need a compatibility check, and how many integrations must be traced. Ask for a fixed-scope quote that lists each of these inputs, which deliverables you receive (inventory, findings, effort estimate) and whether a follow-up review is included. Confirm whether the quote covers only the audit or also a staging run of Upgrade Status and Drupal Rector.
How long does a readiness audit take?
Length depends on what has to be inspected and how quickly the internal team can answer questions. The biggest factors are the number of custom modules and themes, the count of contributed projects, the number of integrations with external systems, and whether a staging copy is ready on day one. Sites with a clean inventory and documented owners move faster than sites where ownership has to be discovered during the work. Ask for the planned timeline in the written scope and confirm which dates depend on your access and review cycles.
What does our internal team need to provide for the audit?
Plan for four inputs before the work starts:
- Read access to the codebase, the Composer files and the lock file, and a staging copy of the production database and files
- An inventory of contributed modules, custom modules, themes and third-party services
- A named owner for each integration, such as identity, CRM, search or payments
- Access to the hosting environment so the PHP version, web server and database can be checked against the requirements
Missing owners are the most common reason findings stall, because integration behavior cannot be judged without someone who knows the expected results.
Can our own team run Upgrade Status and Drupal Rector without a partner?
Yes, a capable Drupal team can run Upgrade Status and Drupal Rector internally. Both are Drupal.org tools and do not require a partner. What a partner adds is experience interpreting the output: deciding which deprecations matter for your business logic, judging whether a contributed module without a compatible release can be replaced, and estimating effort in a way that holds up. If your team has the time and developers who know the codebase, running the tools yourself and reviewing the results with an outside reader is a practical split. Confirm that your team has someone accountable for the final report.
What does a readiness audit not prove?
A readiness audit does not certify your site, issue an attestation and does not replace testing. It identifies deprecated code, hosting gaps and contributed modules that lack a compatible release, and it gives an effort estimate based on what it found. It cannot prove that every business workflow behaves correctly after the upgrade, that performance is acceptable under load or that a compliance assessor will accept your evidence. Those checks belong to functional testing, regression testing and, where needed, independent assessment. Ask the provider to list in the scope what the audit covers and what it leaves to your test plan.
How do the audit findings feed into the later upgrade work?
The findings become the input for the upgrade plan. Each item is tied to a module, theme or hosting component, marked as fixable by automation, requiring manual changes or blocked by a missing release, and grouped by owner. Hosting gaps feed the infrastructure work, such as the PHP 8.3 requirement for Drupal 11 and PHP 8.5 for Drupal 12, and the Drupal 10 end-of-life date of December 9, 2026 shapes the sequence. Ask for the findings in a format your team can track as backlog items, and confirm how the effort estimate maps to the fixed-scope upgrade quote.
How DeployOpen scopes, delivers and supports a Drupal upgrade readiness audit
DeployOpen is a Chainscore Labs company that plans, implements, customizes, hardens, documents and supports self-hosted open-source platforms inside your own infrastructure. For a Drupal upgrade readiness audit, we agree the scope in writing, run the checks against your code and hosting, and hand over a findings report and effort view your team can act on.
How we scope
- Engagements are fixed-scope, with the sites, codebases and environments agreed in writing before work starts.
- The written scope names the target Drupal version, the custom modules and themes in view, and the contributed projects to review.
- Hosting checks cover the PHP version, database engine and web server your target release requires, confirmed against your own environment.
- Ask for the scope to state exactly which Upgrade Status and Drupal Rector runs are included and what is excluded.
How we build
- We run Upgrade Status against custom modules and themes and record each deprecated API use by file and location.
- We apply Drupal Rector to mechanical fixes in a branch, then review each change that it cannot resolve on its own.
- We check each contributed module for a release compatible with the target version and flag projects with no release.
- We turn the findings into a sized list of remaining manual work, grouped by module and by risk.
How we hand over
- You receive a written readiness report covering hosting requirements, deprecated code, contributed module status and open risks.
- The effort estimate lists the work items, the assumptions behind each one and the points where your team needs to decide.
- Findings are tied to the repository, so your developers can reproduce each Upgrade Status and Rector result themselves.
- We walk your engineering and platform leads through the report and agree which items belong in the upgrade backlog.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers once the audit findings are accepted.
- A retainer can cover re-running the audit after your custom code changes, so the effort view stays current before the upgrade starts.
- Ask any provider, including us, to confirm how security advisories for Drupal core and contributed projects will be tracked during the project.

