WordPress Migration Problems and How to Fix Them

Migrating your WordPress site to another location should be a painless process: you just have to export your database, import it to the new host, move your files there, configure everything and make the new site live. However, there are some steps that, when not done right, could provoke several problems that cause trouble and lead to unsuccessful site transfers. In this post, I review the required steps in a WordPress migration to show you the most common problems I have found after three years migrating sites for customers of Migrate To WordPress.

Exporting/Importing your WordPress Database

The first step to start a migration of your WordPress site is to move the contents from your current host to a new server. To do this, you could use the Import/Export native function that WordPress has. However, this may fail or not export/import all of the contents you have defined, but only a subset. To avoid this, I always recommend to go for the database directly, and export a SQL file. But, this may also cause some trouble.

If you have access to your database through phpMyAdmin, just try to export the SQL data following the steps explained in this article about nice phpMyAdmin tutorial to export your data. Depending on the specific configuration of your server and the size of your database, the process of exporting your contents to a SQL file may fail because of memory or timeout errors.

Alternatively, if you do not have access to phpMyAdmin you can try the WordPress plugin Adminer, which provides the same functionality as phpMyAdmin. However, it may also cause memory and timeout errors when trying to export your data. But it is always worth to try it.

Another possibility you have is trying to export the data directly through MySQL commands. If you have SSH access to your servers you can use the command mysqldump to do this:

Export a SQL file from your database

mysqldump -uUSER -pPASSWORD DBNAME > export.sql

Import a SQL file to your database

mysql –uUSER –pPASSWORD DBNAME < export.sql

Remember to change USER, PASSWORD, and DBNAME to the right values in your installation. If you have forgotten these credentials, open your wp-config.php file (when you have access to it) and you’ll find them there.

If that fails to work, producing a timeout error, or mysql and mysqldump are not available, then you need to contact the support team of your current hosting provider and request them to create a backup of your database. After that, you should ask your new hosting provider to import the previous export file into the new database for you.

Transferring Files, Plugins, and Themes

Once you have your database ready, it is time to transfer the files stored in your old WordPress host to the new one. Basically, this means copying all the contents from the following folders:

  • wp-content/themes: here is where all your WordPress themes are located. Just copy all of the contents to this folder, unless you decide to switch to a new theme. In that case, you can ignore these files.
  • wp-content/plugins: here is where all your WordPress plugins are located. Again, copy all the contents to new new host. Note that the plugin configurations are stored in your WordPress database, so after importing the SQL file from the previous steps, everything should work perfectly in your new host.
  • wp-content/uploads: here is where all the media files that appear in the Media Library are located. Note that the size of this folder may be huge when using a lot of images in your site.

Speed Up File Download/Upload

If you have a very big WordPress installation with a lot of media files, file transfers may take ages to download from your host and upload into the new one. If that’s your case, try to do the file transfer in a place where you have a good internet connection, because you’ll probably need it. Fortunately, there are some tips that can help you transferring the media files much faster. Let me review them:

  1. Whenever it is possible, make a compressed archive (.zip, .rar, or similar) of your media files before transferring them. It’s faster (and simpler) to move one big file rather than thousands of small ones. However, some hosting providers do not permit this functionality or do not allow you to have SSH access to your server. If you only have FTP/SFTP access, go to tip 2.
  2. When transferring multiple files from one host to another, avoid using FTP/SFTP directly. Try parallelizing download/upload connections by using LFTP and mirrorcommands.
  3. If you have SSH access to both servers (the old and the new one), transfer your files(or compressed archive file) directly from your old hosting provider to the new server, instead of downloading them locally into your computer and then uploading them from there.

Regarding LFTP, here are the commands that you should use to download and upload the previous folders recursively and with parallel connections, reducing the final amount of time required for the transfer:

Download files to your computer

lftp -c "open ftp://$username:$password@$ftp_hostname;lcd /path/to/local/directory/in/your/computer;cd /path/to/remote/directory/in/ftp/server;mirror --parallel=20 --only-missing;"

Upload files to new host

lftp -c "open ftp://$username:$password@$ftp_hostname;lcd /path/to/local/directory/in/your/computer;cd /path/to/remote/directory/in/ftp/server;mirror --reverse --parallel=20 --only-missing;"

Problems with File Permissions

When you transfer files from one host to another, their permissions are moved too. Some hosts allow you to have files with permissions like 777, which in UNIX means that anybody can have full access to the file (read, write, and execute it). Such file permissions present a huge security risk, and if you are switching to a host that cares about security and forbids this, transferring files may result in an “Internal Server Error” page.

Having SSH access to your server, you can change the permissions of the files through the following command:

chmod -R 644 /path/to/folder/

It is also possible that your new hosting provider allows you to change permissions of your files through an option in their Administration Panel, like WPEngine does:

Fix file permissions in WPEngine
Fix file permissions in WPEngine

Fix Thumbnail Sizes

The moment doing a WordPress migration is the perfect time to redesign your theme or directly switch to a new one. If that’s your case, take a look at your featured images, because it could happen that all the new images that are uploaded after activating the new theme look good, but the old thumbnails appear ugly and distorted. And just trying to adjust image sizes in Settings -> Media, won’t solve the problem.

It is important to note that when you upload an image to WordPress, it creates duplicated images of the original one (called thumbnails) of different sizes and saves them in the uploads folder. What sizes? WordPress gets the image sizes for thumbnails from your theme. Your theme defines the thumbnail sizes, which are really useful to load the best image size when needed. There is no need to load huge images when displaying a list of posts. In these cases, your theme displays smaller thumbnails. Adapting the thumbnail size to each situation improves the final loading time of your WordPress.

Nevertheless, as we have already mentioned, the problem is that these new image sizes are only applied to the images that you upload after activating the new theme. To solve this problem you need to generate new sizes for all the previously uploaded images. This process is often referred to as regenerating thumbnails and, as always, there is a plugin to do that.

In order to do this, you just have to install the plugin Regenerate Thumbnails in your WordPress installation. Then, activate the plugin and  go to Tools -> Regen. Thumbnails. Press the button Regenerate All Thumbnails to start regenerating the thumbnails for all image uploads. You can also regenerate the thumbnails for individual image uploads or specific multiple image uploads in Media -> Library.

Regenerate thumbnails in WordPress
Regenerate thumbnails in WordPress

Note that this plugin does not delete previously created thumbnails by old themes. This is something you should do manually if you are sure that you haven’t used those sizes anywhere on your website. Look for images inside your wp-content/uploads folder in WordPress that have old unused dimensions. Be careful when deleting them; it will free space in your hosting disk, but it can also have side-effects on your site when deleting wrong images (images that you actually use).

Regenerating thumbnails is very handy if you’ve changed any of your thumbnail dimensions (via Settings -> Media) after previously uploading images, or have switched to a theme with different featured image dimensions.

WordPress Configuration after Migration

This part can be tricky too. Your database has lots of references to your old site. If you changed your domain name in a migration, trying to access to your new WordPress site after importing your database file will result in several redirection problems. The reason for this is that your WordPress thinks that it is located in your old server with your old domain. To solve these wrong URL address problems, continue reading.

Telling WordPress that the Site’s Location Has Changed

WordPress stores your site location on the wp_options table. You can see it when you go to to Settings -> General:

Settings -> General in WordPress
Settings -> General in WordPress

If the URL you see there is not the URL of the new domain, WordPress will always redirect you to the URL you have there. In order to easily fix this issue, search for the following lines in your wp-config.php file (or add them to the end of that file) and put there your correct URL:

define('WP_HOME', 'http://my-domain.com');
define('WP_SITEURL', 'http://my-domain.com');

These two statements tell WordPress to ignore the values in the database and use the home and site URL values that you specify in the wp-config.php file.

Updating URLs in Posts and Custom Fields

When you change the domain name, you need to update all the posts and custom fields that include the old URL with the URL of the new domain. When you insert a link or an image, WordPress will store it with its full path. All these absolute references have to be replaced when you’re moving to the new domain. Otherwise, all inline link and images still point to the previous domain, producing 404 errors.

To fix this, we can directly go to phpMyAdmin and access our WordPress database. Before doing anything, you should backup the database, using the export function we described before. Afterwards, you can apply the following SQL statements:

UPDATE wp_options SET option_value = REPLACE(option_value, 'http://my-old-domain.com', 'http://new-domain.com') WHERE option_value NOT LIKE '%{%';
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'http://my-old-domain.com', 'http://new-domain.com') WHERE meta_value NOT LIKE '%{%';
UPDATE wp_posts SET guid = REPLACE(guid, 'http://my-old-domain.com', 'http://new-domain.com');

Once you have run each of these update statements, phpMyAdmin will tell you how many rows in your database were updated. Check that this number makes sense.

Note that I’ve excluded rows that have the character { in them as they would be part of serialized arrays. To replace URLs (or any other string) inside serialized arrays, go to the next section

Fixing Serialized Arrays in PHP

Serialization has become a standard in many programming languages. The problem with serialization is data portability. Let’s see an example of serialized data in PHP:


As you can see, the data is organized in a way that it has data types and number of elements in every data type. Concretely, there is a String URL that contains 67 characters. And that’s the problem.

If you change your domain, replacing it is not enough. If the old and new domain don’t have the same number of characters, and you search and replace the domain URLs in your database, you could get in trouble and corrupt your content data.

There’s no way to update serialized arrays using just MySQL queries. You need to use PHP, load the arrays, find the values, replace them and serialize back. That’s very tedious and error prone, but there are several tools that help you doing the hard job. My recommendation is to use a plugin that does the complete migration for you. WP Migrate DBDuplicator, or All-in-One WP Migration are some examples of good plugins for this task, and they take care of replacing the serialized arrays.

Alternatively, you can use this WordPress search and replace database tool. It carries out database wide search/replace actions that don’t damage PHP serialized strings or objects with a user friendly interface.

Change DNS to Point Target Site

Once you have the new WordPress installation ready to be live, the final step of migrating your website is the DNS change. This is something that only experienced people should do, because it may cause your site to go down. And you don’t want that!

Sometimes, it is better to contact the support team of both your old and new hosting providers. They will help you and provide the right instructions to follow when performing the DNS change. Note that domain records changes need a propagation period to take place. This time is required because all of the world’s DNS servers need to update their records about your domain name.

In addition to it, while waiting for the DNS propagation period to pass, you can disable the comments and login on your old hosting. This way, you avoid losing new comments or other user activity during the so-called propagation period. When doing the DNS change, be careful with your email configurations. It may be the case that when changing some records in the DNS configuration, you destroy your mail records. Again, and sorry to repeat this, contact a professional to perform this change and ensure that you won’t lose anything.

If you liked this article, let me know by sharing it through your social networks or by writing a comment. And if something is missing, we can work together to include it on the list.

Leave a Reply

Your email address will not be published. Required fields are marked *