On this page
- Drupal 6 or 7 source site
- Potential ID conflicts
- The problem
- Scenarios that might lead to ID conflicts
- Solutions
- Statistics
- Views
- Drupal 6 source site
- Aggregator Categories
- Allowed protocols
- Allowed vocabularies of taxonomy term reference field
- Fields missing on the edit form or the view page
- Homepage loads and the theme is broken
- Menu UI
- Modules and themes
- Node content types
- Profile categories
- Profile field (list selection)
- Text/Input formats
- Time Zones and Dates
- URL Aliases
- Who's online block
- Drupal 7 source site
- Blocked IPs
- Comment types
- Important note: Drupal 8+ Standard installation profile and Article content type
- Entity Translation
- Field Collection
- PHP Code
- Duplicate field _config_instances
- The problem
- The solution
- Files
- File entity
- Migrating Files fails
- Plain Text Fields
- Conflicting text processing settings in Drupal 7
- Text with summary + plain text formatting setting in Drupal 7
- Text with summary: Individual value, summary and format migration through one process plugin
- Rules
Known issues when upgrading from Drupal 6 or 7
The following is a list of various items that may require special attention when migrating.
Drupal 6 or 7 source site
Potential ID conflicts
The problem
As described on the preparing an upgrade page, the destination site should be completely empty when the upgrade process is performed. The migration process preserves the IDs of the source site when importing them into the destination site. If the content has been created on the destination site before the upgrade (e.g. node with nid 1), it is likely that the IDs will conflict.
The user is warned of potential ID conflicts than can choose to continue with the upgrade or not. Site administrators should carefully consider potential conflicts. If ID conflicts are not treated with care, content or other entity items such as taxonomy terms and files can be overwritten causing data loss. It is also possible that the referencing entities are damaged, for example, content can be associated with an incorrect taxonomy term.
Scenarios that might lead to ID conflicts
- The destination site had already been in use at the time of the upgrade and content had already been created.
- The initial migration was completed. After the initial migration content or other entities were created in both the source and the destination sites. When the updated / newly created content was migrated from the source site, the IDs may conflict with the content that was created in the destination site.
- The destination was in a clean state but contributed or custom modules might have added data for their own use when they were enabled in the destination site. For example, since Drupal 8 the Forum module creates a taxonomy term for its General Discussion category and that will normally get ID #1 in a fresh install. If the source data contains a taxonomy term with ID 1, it will overwrite the name of the forum's General Discussion category.
- The source might have data that do not come with an ID, but the destination requires them to have an ID. For example, Drupal 6 handles user pictures as unmanaged files without an ID but the destination requires them to have an ID. Managed file fields with IDs will be created during the migration and these may conflict with files that are yet to be migrated.
- Possible ID conflicts with translations are not automatically detected.
- If you are executing a complete upgrade at once and you are performing the upgrade to an empty destination site, everything should be OK.
- If you are executing a partial migration after an initial upgrade AND you have added translations on your destination site before migrating the updated / newly created content, the second migration may overwrite the translation made on the destination site.
Solutions
Custom migration for the conflicting items
It is possible to customize the migration for the problematic content so that new IDs are created for the problematic items. Note that this will affect their internal path and possibly their public URLs. Special care should be taken to correct any references to the changed entities.
Manipulate auto-increment values
When the destination does not have any conflicting data but the migration process may generate conflicts, it is possible to manipulate the AUTO_INCREMENT value on the destination database tables so that the IDs of the created entities do not fall within the range of other migrated entities. The migration of user pictures described above is an example of this.
Accept that data may be overwritten
It is always possible to go ahead with performing the migration. This is probably not the desired solution in many cases as it may lead to data loss.
Statistics
The access log settings and non-i18n statistics data are migrated. Consolidation of i18n statistics data are migrated as of Drupal 8.5.2. See #2930101: i18n / statistics - node counter not updated for translations.
Views
Views are not migrated, you will need to create the views in the destination site manually. For further details, please refer to #2500547: Upgrade path for Views from Drupal 6 and 7. Note that the Views Migration and Views migration from Drupal 6 or 7 modules exist to make a "best-effort" attempt, but results will need testing, particularly with more advanced views.
Drupal 6 source site
Aggregator Categories
Since Drupal 8, Drupal no longer has the concept of aggregator categories and therefore they're not migrated.
Allowed protocols
Since Drupal 8 the protocols in the "filter_protocols" are stored as a container parameter, so in case you had changed the variable "filter_allowed_protocols", enter it into your services.yml
file.
Allowed vocabularies of taxonomy term reference field
In Drupal 6, the list of applicable content types for a given vocabulary is defined in vocabulary settings. As of Drupal 8, the allowed vocabularies can be defined on taxonomy term reference field settings. This setting is currently not migrated, allowing all vocabularies to be referenced in destination site. See #3042533: D6 taxonomy term fields are not migrated with allowed vocabularies. You can manually edit the taxonomy term reference field settings in the destination site after the upgrade and select the allowed vocabulary.
Fields missing on the edit form or the view page
One other thing that may be a point of confusion is when you run a migration that seems to be successful but afterward, you don't see your fields on the edit form. Go to the Content Types administration page and check the Manage Form Display tab for each content type. The fields added by the upgrade may be hidden on the edit form. If so, drag them up to be visible. Similarly, if they don't appear in the node view, the fields added by Migrate may have gotten hidden on the Manage Display tab and you may need to make them visible there. In migrating custom fields on an entity, the Migrate Plus module could help.
Homepage loads and the theme is broken
When running migrations, sometimes the page is white and only loads a few items. Basically, it looks like a broken theme. Visiting /user and returning to the home page normally resolves it.
Menu UI
The menu_primary_links_source and menu_secondary_links_source variables are not migrated, because they do not have counterparts in Drupal 8+.
Modules and themes
Before starting the migration, new modules and themes should be enabled, as well as the admin theme (if there is one) set.
Node content types
The default configuration in Drupal 6 has Story and Page content types. In Drupal 8+ the default content types are called Article and Basic Page (which has a machine name 'page' just like in Drupal 6).
- Migration will map the Drupal 6 Page to Page content type because the machine names of these content types match.
- Migration will create the Story content type in the destination site. You might want to delete the Drupal 8+ Article content type if you don't need it. For further details, please refer to #2236289: Migrating "story" nodes from D6 creates new content type in D8.
Profile categories
Fields grouped by the Profile module in Drupal 6 will not be grouped in Drupal 8+.
Profile field (list selection)
The "allowed values" setting of the resulting field in the destination will be a combination of all selected user values and the currently allowed values in Drupal 6 and not just the allowed values in Drupal 6.
Text/Input formats
Filter formats not recognized by the destination site will be migrated as filter_null, a filter that simply returns an empty string. This means that any Input format using an unknown filter format won't display fields' content, although the content is in the database. It may be confusing. See #2618332: Better handle replacement of missing filters with filter_null and #2630578: Formats duplicated in D6 upgrade regarding ways to improve this.
Filter formats not recognized include the infamous PHP code filter, and any other filter provided by a contrib module that is not available in your destination site..
The PHP filter is not supported in Drupal 8+—it's very bad practice, but you can use the PHP module for that if you really must.
To repair this situation, you have several alternatives:
- Check if the modules providing the filters have a Drupal 8+ version and install them
- Edit and save the affected input formats. This will remove the reference to format_null, and the contents will start showing. Note that since the original filter doesn't exist, contents are not being filtered and unreplaced tokens may be shown, or even the site can be exposed to any security issue
- Edit the contents and change to another input format. This suffers the same problems as the previous point
Time Zones and Dates
Drupal 6 uses a time zone offset to compute local time. Drupal 7+ or higher use a time zone name. Unfortunately, the PHP function timezone_name_from_abbr()
which converts the offset to time zone names will produce different time zone names depending upon whether or not daylight savings time is turned on or not on your server. For example, the time offset of 3600 converts to Europe/Paris if daylight saving time is off and Europe/London if the daylight saving time is on. The migration is set to ignore daylight saving time.
In time zones that use Daylight Saving Time, a date could be interpreted differently by Drupal 8+ compared with Drupal 6. For example, if the time is around midnight, the date could be seen as a different day. This causes problems especially if date tokens are used to build paths (e.g. URL aliases, file field paths). Two possible solutions are shown in #2926421: Handle date inconsistencies between D6 and D8.
URL Aliases
When migrating URL aliases for a language that is not enabled on the destination site, none of the aliases will work until you enable the language on the destination site.
Who's online block
The User activity settings are not migrated. This needs to be manually edited in the relevant View under filters/access (#2169327: Migrate the User Activity block setting).
Drupal 7 source site
Blocked IPs
The IP address is migrated. However, the id column from Drupal 7's ban_ip table is not migrated and because of this every IP address migrated will produce a notice message, [notice] New object was not saved, no error provided
and it is not possible to roll back the migration.
Comment types
Drupal 7 allows the comments to have different fields on different content types. Typically the comments have Author, Subject and Comment body fields. Because the different Drupal 7 comments can have different fields, the migrations will create separate comment types for each content type:
- Content type Foo will have a comment type comment_node_foo
- Content type Bar will have a comment type comment_node_bar
The only exception to this is Forum comments. When the Forum module is enabled, comment type comment_forum is automatically created. The D7 Forum comments are migrated to this comment type.
Important note: Drupal 8+ Standard installation profile and Article content type
If your destination site was installed using the Standard installation profile you will have a content type called Article.
- This content type will come with a comment field called "comment".
- The migration system can not assume that the destination site was installed using the Standard installation profile. Therefore a comment type comment_node_article will be created and comments of the D7 Article content type will be migrated to this comment type.
As a result, your Article content type will now have two comment fields:
- comment which came from Drupal 8+ Standard installation profile and is not used
- comment_node_article which the migration system created
You most probably don't want to have two comment fields on the Article content type so you need to manually delete the comment comment field from Article (admin/structure/types/manage/article/fields). After you've done this, you may also want to delete the comment comment type (admin/structure/comment) if you're not using the comment comment type anywhere else.
It is recommended that the unnecessary comment field is removed from the Article content type before running the migrations because Drupal 8+ currently has a bug related to comment field deletion, see #2906470: Orphan comments and entries in comment_entity_statistics after comment field instance has been deleted.
Entity Translation
Some Drupal 7 sites using the Entity Translation module will not have the entity_translation_revision table needed to successfully migrate. This can be resolved by running on the source site the updates (entity_translation_update_*()
) added by #2402247: [UNSUPPORTED] Migrate translation for enable revision. More information is available in #2396103: [DATA LOSS] Translations deleted.
Field Collection
- Deprecated in Drupal 8, use Paragraphs module instead.
- To migrate the Field Collection fields and data to Paragraphs when upgrading from Drupal 7 to 9, make sure Field Collection to Paragraphs module is installed beforehand.
PHP Code
Filter formats not recognized will be migrated as filter_null, a filter that simply returns an empty string. This means that any Input format using an unknown filter format won't display fields' content, although the content is in the database. It may be confusing. See #2618332: Better handle replacement of missing filters with filter_null and #2630578: Formats duplicated in D6 upgrade regarding ways to improve this.
Filter formats not recognized include the infamous PHP code filter, and any other filter provided by a contrib module that is not available in your Drupal 8+ installation.
The PHP filter is not supported in Drupal 8 + —it's very bad practice, but you can use the PHP module for that if you really must.
To repair this situation, you have several alternatives:
- Check if the modules providing the filters have a Drupal 8+ version and install them
- Edit and save the affected input formats. This will remove the reference to format_null, and the contents will start showing. Note that since the original filter doesn't exist, contents are not being filtered and unreplaced tokens may be shown, or even the site can be exposed to any security issue
- Edit the contents and change to another input format. This suffers the same problems as the previous point
Duplicate field _config_instances
The problem
Drupal 7 allows duplicate field_name_bundle entries in their "field_config_instance" database. The "field_name_bundle" is a Drupal 8+ index key which consists of "field_name", "entity_type" and "bundle". This index key is unfortunately NOT unique and therefore allows multiple duplicate entries.
This leads to migrations, which depend on "upgrade_d7_field_instance" to throw the following error while migrating, even if "upgrade_d7_field_instance" successfully migrated before
[error] Migration upgrade_d7_field_instance_widget_settings did not meet the requirements. Missing migrations upgrade_d7_field_instance. requirements: upgrade_d7_field_instance.
The solution
Look for duplicate "field_name", "entity_type", "bundle" combinated entries inside the "field_config_instance" d7 source database and delete them.
For more information, see #3307506: "Missing migrations upgrade_d7_field_instance" because of duplicate field_name_bundle entries in D7 field_config_instance.
Files
File entity
If your source Drupal 7 site is using File Entity then the filename in the database may be the title not the filename on disk. After the migration this may result in errors when editing migration content type that use a file field. To prevent this a custom migration is needed. An example is in #3022910: Prevent migrated files from having an incorrect value at file_managed.filename.
Migrating Files fails
If your source Drupal 7 site is using a non-standard path for the public file system i.e anything other than sites/default/files
, you may experience issues when attempting to migrate physical files:
Migrating Files and assets
[notice] Processed 7065 items (0 created, 0 updated, 7065 failed, 0 ignored) - done with 'upgrade_d7_file'
[error] upgrade_d7_file Migration - 7065 failed.
This means Drupal 8+ can read that there are 7065 file entities in the Drupal 7 database, but it can't reach the physical files themselves. This error will also lead to the Media entity migration failing, as the files are not present for the entity to link.
This may be because regardless of the file location you specify in your file migration (migrate_plus.migration.upgrade_d7_file.yml
), and any override for the system file path defined in settings.php
, the Migrate module will query the Drupal 7 database directly to get the file path and ignores all other settings.
The file path the Migrate modules use will be stored in the variable file_public_path
.
To check what your Drupal 7 system file path is, in your D7 site run $ drush vget file_public_path
, and $ drush vget file_temporary_path
for temp files.
Note: However, that the vget
result can be misleading. If you have specified a different file path in your settings.php
or settings.local.php
, the drush command will return that value instead, NOT the value stored in the database! To ensure you get the value Migrate will use, ensure you haven't overridden the file path in D7's settings.php
or settings.local.php
:
$conf['file_public_path'] = '/my/great/file/path';
$conf['file_temporary_path'] = '/some/temp/path';
Remove any overrides, then check the variable value. If you want to change it, run: $ drush vset file_public_path = /place/my/files/live
(normally sites/default/files
).
Plain Text Fields
Conflicting text processing settings in Drupal 7
In Drupal 7, the text processing settings are defined on Field instance settings. In other words, the same field can be used on two (or more) content types and the text processing settings can be Plain text on one content type and Filtered text on another.
Drupal 8+ has separate field storage types Text (plain) and Text (formatted). There's also Text (plain, long) and Text (formatted, long). The important part here is that this selection is done on the field storage level. In other words, the plain/formatted selection can't be changed per content type.
The migration system makes no assumptions. If the migration system detects conflicting text processing settings, these fields are skipped with a log message. The site builder has two options:
1. The text processing settings can be altered on a Drupal 7 site so that all content types that use the text field have the same text processing setting.
- Pay attention when selecting which way to harmonize the processing settings to avoid possible cross-site scripting (XSS) security issues.
- If your field was set to Plain text in Drupal 7 and untrusted users were able to post content to this field, it is possible that the fields contain malicious input. This was not leading to an XSS on your Drupal 7 site because the field was set to Plain text and thus the malicious input was not executed. If you now change the field now to Filtered text, make sure that the Text format is not Full HTML or similar which would allow the malicious input.
2. If you need to have two different formatting settings in the destination site, you need to develop a custom migration that splits the Drupal 7 fields into two separate fields. Find more information on customizing the migrations read Customize migrations.
Text with summary + plain text formatting setting in Drupal 7
Drupal 7 has a field type with Long text and summary. The corresponding field type in Drupal 8+ is Text (formatted, long, with summary). In Drupal 7 it is possible to configure on field instance settings that the text processing is Plain text. The Text (formatted, long, with summary) fields are always formatted text in Drupal 8+.
The migration system makes no assumptions. If the migration system detects a Long text and summary field with Plain text formatting settings, the field is skipped with a log message. The site builder has the same two options as above:
1. Change the field formatting setting from Plain text to Filtered text in Drupal 7.
- The same remark described above about cross-site scripting applies here.
2. Create a custom migration path and build your own logic on how you want to migrate the fields to the destination site. Find more information on customizing the migrations read Customize migrations.
Text with summary: Individual value, summary and format migration through one process plugin
Sometimes it is needed to migrate the value, summary and format of a textarea field for a certain content bundle individually, because you are using different filter formats on your d9 site, compared to your d7 site. So instead of using the generated "get" process plugin, example:
process:
body:
-
plugin: get
source: body
We can use the "sub_process" plugin instead, to individually process "value", "summary" and "format" like this:
process:
body:
plugin: sub_process
source: body
process:
value: value
summary: summary
format:
plugin: static_map
source: format
map:
full_html: full_html
filtered_html: basic_html
pure_html: full_html
plain_text: plain_text
php_code: full_html
This way, it is possible to use different plugins for each textarea attribute, like "static_map" in the example above, or just plainly map the data (e.g. value: value). If you do not want to override every single generated Migration YAML, you can also perform the override using "hook_migrations_plugins_alter()".
Rules
- Since the inner workings are different from Drupal 7, make sure to read D8 Rules Essentials beforehand.
- Trouble with before content save? #3026148: Editing a field upon content save might help.
- There is an issue in the Rules project for writing a migration. #2899453: Support for core Migrate - migrated D6, D7 Rules to D8.
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion