Drupal migration: where content transfer breaks
Transferring content between Drupal versions or to a new platform almost never goes "in a single run".
The main reason is that content in Drupal does not live on its own: a piece of content is tied to taxonomy, reference fields pointing to other entities, files, menus, and access permissions.
The Migrate module transfers entities one by one and by default does not guarantee that a related entity already exists at the moment of import.
This leads to three classic failures: broken links to not-yet-created content, duplicates on re-run, and mismatched taxonomy, when terms are created anew instead of being linked to existing ones.
Broken links appear when the order of migrations is not arranged: a piece of content references an entity that does not yet exist in the new database.
Duplicates are a consequence of the lack of idempotency: without explicit mapping of the source identifier, a re-run creates copies instead of updating.
Taxonomy breaks the most quietly: terms with the same name but different source identifiers collapse or multiply, and filters on the site start returning empty result sets.
We start not with running the import, but with a relationship map: which entities reference what and in what order to transfer them.
Then we set up identifier mapping so that a re-run updates records instead of spawning duplicates, and we verify the integrity of relationships before making the site available to visitors. We break down how this is resolved for each type of failure.
What managed content migration delivers
Content integrity instead of manual reconciliation
The Migrate module transfers content along with its relationships: taxonomy, links between nodes, media and field attachments.
Relationships are restored using source identifiers rather than being reassembled by hand, so after the transfer there are no "dangling" links or orphaned terms left behind.
Integrity checking becomes part of the process itself: discrepancies are visible immediately rather than surfacing a month later in search.
Migration time is reduced many times over
Each content type is described by its own set of rules, and the transfer runs in batches rather than one record at a time. Where manual migration took weeks, managed migration fits into days, and a re-run after edits takes hours.
Migration automation removes the main source of delays: waiting for a person to transfer the next portion of content.
Relationship checking is predictable
Before the transfer, checks are configured: how many records are expected on output, whether all links resolved, whether any attachments were lost. The result is compared against the source data by counters, and deviations are visible before publication. This removes the risk that part of a catalog or blog simply won't make it to the new version.
Rollback and re-run without losses
The transfer runs in a test environment, where it can be run as many times as needed. If the rules were refined, the run is repeated on a clean database, and the result is checked again.
This cycle provides confidence that the production transfer will follow an already-tested scenario rather than becoming an experiment on a live site.
Migration methods: comparing approaches
Moving content into Drupal almost never comes down to "export and upload it back": materials have relationships with taxonomy, links between entities, revisions, and field metadata.
The choice of approach determines what a re-run will cost when something breaks on the test copy, and whether the migration will remain reproducible.
Below are three real options that teams choose between at the start of a project, along with their boundaries of applicability.
| Approach | When it fits | Limitations |
|---|---|---|
| Manual migration through the interface | One-off volumes of dozens of items, varied source formats, no repeatability | Does not scale, errors are not tracked, relationships and revisions are lost, a re-run starts from scratch |
| Migration scripts (custom code) | A non-standard source or transformation logic that ready-made solutions do not cover | Requires code maintenance, no unified log or rollback, every change to the source means editing the script |
| The Migrate module | A structured source, regular or large migrations, repeatability required | Requires describing field mapping, and non-standard sources need a custom plugin |
The Migrate module describes a migration declaratively: the source, field processors, and destination are defined by configuration rather than by code written "here and now".
This provides what the first two approaches lack — a run can be repeated on a clean database and produce the same result, and discrepancies are visible in the report instead of surfacing a month later in production.
Manual migration and scripts are not ruled out: for a dozen pages or a source without structure, they are faster. But as soon as the volume grows or the migration needs to be repeated after edits, the declarative approach pays off — let's break down how this works in practice.
How Drupal migration setup works
Migration setup in Drupal is not a one-time import, but a managed process with reproducible steps. The Migrate module describes the transfer declaratively: what we take from where, how we transform it, and where we put it.
That is why the result is reproducible on test and production environments, rather than depending on manual edits.
- Content audit. We inventory the source entities: content types, taxonomies, users, files, and the relationships between them. We record volumes, duplicates, broken links, and fields with no counterpart in the target model — this determines the scope of work, not design preferences.
- Mapping schema. We build a "source → Drupal entity" map: which fields become fields, what goes into taxonomies, and how nested structures and media are transferred. For every discrepancy we decide in advance — transformation, merging, or a deliberate decision to drop the data.
- Migration setup. We describe the transfer processes with handling of text, dates, links, and files, and configure dependencies between steps so that content does not arrive before its reference data. We run it on a copy and refine it until the result is clean.
- Integrity check. We verify record counts, relationships, access permissions, and correct display. We separately test re-running: the migration should update content, not duplicate it.
- Transfer and acceptance. We perform the final run in an agreed window, record a rollback point, and hand the team documentation on running and re-applying the migration.
This order eliminates the main risk of migration — a discrepancy between what was transferred and what was expected to be seen. Describe your task — we will come back with an estimate and a work plan.
Output artifacts: configurations and runbooks
We hand over not a "project archive" but a working migration system that your team can run and evolve without us. Every artifact lives in a repository, with change history and environment bindings.
- Migration configurations — a set of transfer rules as declarative files: sources, field mapping, value handlers, dependencies between datasets. The transfer is reproduced with a single command, not manual edits in the interface.
- Data schemas — a "source → target structure" mapping: content types, taxonomies, relations, reference fields. It shows what moves where and where transformations are needed.
- Access policies — roles, read and publish rights for the migrated content, rules for service and archived materials. So that after the switch no one loses access or gains extra access.
- Launch runbook — the sequence of actions: environment preparation, dry run on a copy, volume reconciliation, switchover, rollback. With checkpoints and owners at each step.
- Rollback runbook — how to return to the previous state if reconciliation fails: saved snapshots, restoration order, stop criteria.
- Documentation — a description of the transfer logic, known limitations, and common errors with solutions. Enough for a new engineer to figure things out without verbal explanations.
- Reconciliation reports — run logs: how many records were transferred, how many were rejected and why. This is proof of migration completeness, not a promise.
The package covers the entire cycle: from the first test run to post-switchover support. Describe your task — we will come back with an estimate and a migration work plan.
Case study: migrating a catalog without losing relationships
The client came with a catalog on Drupal: about 40,000 items, three entity types linked to each other via references to taxonomy terms and to files.
The previous contractor migrated content with scripts on top of direct database writes — some of the "item → term" relationships remained in the old tables, and some were duplicated.
In production it looked like this: 18% of the cards had related sections that wouldn't open, and editors fixed the relationships by hand — 6-8 minutes per card.
What it was before
- Lost "item → term" relationships: about 7,200 (18% of the catalog).
- Broken file links: 1,400, with some media stored outside managed storage.
- Recovery after a failed run: a day and a half — the rollback was done from a database dump, because no one recorded intermediate states.
- Manual fixes: two weeks of editors' work, and afterwards the relationships drifted apart again on the next import.
What was changed
We built migrations on the stock Migrate module: each entity type is a separate set of rules, and relationships are assigned during the processing stage rather than afterwards.
We create taxonomy terms and media first and store the "old identifier → new" mapping in a separate table — relationships are restored deterministically from it, without guessing by name.
The run happens in staging, and the result is reconciled against the source before switching production.
What it became
- Lost relationships: 0, discrepancy with the source — 0 rows on the control reconciliation.
- Broken file links: 0, all media migrated to managed storage.
- Full run: 40 minutes, a repeat run is idempotent — no duplicates appear.
- Recovery after a failure: 12 minutes — rollback to the last recorded state instead of deploying a dump.
- Manual fixes by editors: not required.
We also handed the client a migration map: which fields map to what, where the rules allow a discrepancy, and how to run the migration again on the next catalog update.
How is Drupal migration different from manual transfer?
Manual transfer is when a content manager opens an old page and copies the text, images, and fields into a new one.
Across ten items the difference is unnoticeable, but at a thousand the divergence begins: somewhere an image's alt text was lost, somewhere the taxonomy wasn't carried over, somewhere a broken link to the old address remained.
It's impossible to check this by eye across the entire volume, and errors surface only after launch, once search engines have re-crawled the site.
Drupal migration via the Migrate module works differently: you describe the transfer rules once — where the entity comes from, how fields are mapped, what to do with nested relationships — and from there the process runs in batches across the entire database.
Every item passes through the same rules, so the thousandth page is transferred just as precisely as the first. This is the main answer regarding reliability: not "more carefully," but reproducibly.
Speed here, too, isn't about "faster by hand," but about the fact that the process doesn't depend on man-hours.
The transfer runs in batches in the background, it can be stopped and resumed from where it left off, and before launch it can be run on a copy of the database and the result verified.
Manual transfer can't be checked this way: to determine that everything matched up, you have to go through the entire volume by eye again.
There's a third difference as well — reversibility. Migration leaves a log: which records were processed, which were skipped, and why.
If after launch it turns out that some items need to be transferred differently, the rule is fixed and only the affected batches are rerun, without touching what's already been transferred. With manual transfer, a rollback means redoing the work from scratch.
That's why the choice between the Migrate module and manual transfer isn't about the convenience of the tool, but about whether you're ready to be responsible for data integrity across the entire volume.
Up to a few dozen pages, the manual path is justified; beyond that, the cost of an error grows faster than the volume.
Common technical concerns
The first and most frequent concern is that migration will require taking down an already running site.
In practice, we transfer content to a copy of the production database, verify the result, and only then switch the traffic: visitors continue working on the current version, and the downtime window is reduced to minutes.
If the site is deployed and actively being populated, we first capture a synchronization point, transfer the bulk of the data, and then catch up on the changes accumulated during the transfer with a second pass through the change log.
What to do with non-standard fields and content types?
Standard entities are transferred using standard rules, but fields added for a specific task require separate mapping. We describe each such field in the migration configuration, define the value transformation and the order of processing links between materials.
If the structure of the source and the target differs, we transfer the data into an intermediate layer and distribute it into the required fields on the target side — this way non-standard content is not lost and does not turn into garbage.
How is integrity verified after the transfer?
We verify not "by eye" but by checksums: the number of materials of each type, the number of attached files and images, the completeness of required fields, and the preservation of relationships between entities.
Separately, we check that no material is left without an author, category, or page address. Discrepancies go into a report indicating the specific records — we handle them individually rather than restarting the entire migration from scratch.
Can we roll back if something goes wrong?
Yes. The transfer goes to a copy, so the production site remains untouched until the moment of switching. Before the final launch, we save a full snapshot of the database and files — if there is any doubt, we return to it and repeat the transfer with a corrected configuration. Rollback does not require manual content restoration: returning to the snapshot takes minutes.
What about page addresses and search results?
We preserve the old addresses or set up redirects to the new ones so that accumulated traffic and rankings are not lost. We prepare the address map before switching, and after launch we verify that all key pages open at their previous links without errors.
Let's discuss your migration task
To come back with a migration estimate rather than generalities, we need a minimum of input from you: the current platform and its version, the volume of content by entity type, the number of languages, a list of integrations, and hard deadlines, if any.
That is enough to understand the migration scheme, estimate the effort, and give a realistic timeline.
Next, we will analyze the data structure on the source side, map it against the content models and fields on the target side, and separately go through files, links, taxonomy, and users.
As a result, you will receive a work plan with stages, checkpoints, and the migration sequence — with no surprises along the way.
- Analysis of the current storage: content types, fields, relationships, taxonomy, media, users, and roles.
- Mapping scheme: what is migrated one-to-one, what requires transformation, and what is deliberately discarded.
- Migration sequence: content, files, links, metadata, redirects — with verification at every step.
- Verification plan: record count reconciliation, selective field validation, checking for broken links and images.
- Rollback strategy: how to return to the original state if acceptance reveals discrepancies.
- Estimate of timelines and scope of work by stage — taking into account your deadlines and volume.
- Post-migration support policy: updates, backups, availability monitoring.
Describe the task — platform, volume, and constraints. We will come back with a migration estimate and a work plan that shows what we do and in what sequence.







