Every common post-migration error (404s, the 500 error, database connection failures, redirect loops, missing images) with the real cause and the exact fix for each.
Your site broke after a migration. Here is how to fix it
I have cleaned up after a lot of migrations, from one-page small-business sites up to 13-plus newspaper blogs across the Postmedia network landing on WordPress VIP. After enough of them you stop being surprised. The errors that follow a move are remarkably predictable, and almost all of them trace back to three root causes worth memorizing. The database points at the wrong URL. The connection details in wp-config.php are wrong. Or the server’s rewrite rules and file paths did not move cleanly. Work out which of those three is true and most errors on this page resolve in minutes. The genuinely ugly ones that survive all three checks almost always turn out to be a redirect or taxonomy problem in disguise, and I will flag those as we go.
Think of this as a troubleshooting hub. Each section below tackles one error. You get the 404 error, error 500, the error establishing a database connection, too many redirects, a generic page not found, images not showing after migration, and All-in-One WP Migration not working. For each, I give you the symptom, what actually causes it, and the exact fix. Everything is mirrored in the FAQ at the end so you can scan for your symptom and jump straight to it.
If you would rather not touch live files, a managed WordPress Migration service handles the move and the cleanup so these errors never reach your visitors.
Diagnose before you fix
Five minutes of diagnosis saves an hour of guessing. Run through these checks before you edit a single file.
Turn on WordPress debug logging
Add the following to wp-config.php, above the line that says “That’s all, stop editing”. It writes errors to wp-content/debug.log instead of dumping them on screen, or alongside the screen if you prefer.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );Check the server error log
Your host’s error_log (in the site root, or in the hosting dashboard) usually names the exact PHP file and line that failed. For a 500 error, this is the single most useful file you can read. Read it first.
Know what changed
Did the domain change, the server or host change, or both? That one question narrows everything. A domain change points you at URL fixes such as redirects, images, and links. A host change points you at wp-config.php credentials. If you are mid-move, the moving WordPress to a new host guide and the manual migration without a plugin guide walk the full process so you can spot the step you skipped.
WordPress 404 error after migration
Flush your permalinks first. Go to Settings → Permalinks and click Save Changes without altering anything. That forces WordPress to regenerate its rewrite rules and rebuild .htaccess. Stale rewrite rules are far and away the most common reason posts and pages return 404 right after a move, so start there before you touch anything else.
Why it happens
Move to a new server or domain and the rewrite rules often do not come along for the ride. WordPress still knows every page exists. The web server, though, no longer knows how to route a pretty URL like /about/ to it, so back comes a 404. As WPBeginner puts it, this is a rewrite-rule problem, not missing content. Your posts are fine. The routing is not.
The fix, step by step
- Confirm your URLs are correct in Settings → General (both WordPress Address and Site Address point at the new domain, with
https://and no trailing slash). - Go to Settings → Permalinks and click Save Changes. Do not change the structure. This flushes rewrite rules.
- If 404s persist, the
.htaccessfile may be missing or stale. Via FTP, rename it to.htaccess_old, then save permalinks again so WordPress writes a fresh one. - If WordPress reports it cannot write the file, set the root folder permission to
755and save permalinks once more, as Cloudways notes.
When the 404 is structural, not a flush
A flush fixes the common case. What it cannot fix is a URL structure that genuinely changed in the move. I worked on migrating 13-plus newspaper blogs across the Postmedia network onto WordPress VIP, the National Post among them, and that project taught me this the hard way. Every publication ran on different legacy software, so the content came in shaped differently from each one. An import that ran clean for one paper would choke on the next, and at first the failures made no sense. I would chase a broken import for an hour before realizing the source data simply did not match the assumptions that worked on the previous publication. Fold that many inconsistent source structures into one new URL scheme and a chunk of your old URLs no longer exist at the same path, full stop. No amount of flushing brings them back. That is a redirect job wearing a 404 costume. If your 404s survive a flush and the paths really did change, build a redirect map. The redirect section below and the migration guide cover how.
On Nginx
Nginx ignores .htaccess entirely. So if your new host runs Nginx, your host has to add the WordPress rewrite block to the server config. Flushing permalinks on its own will not touch an Nginx 404.
Error 500 (internal server error)
Nine times out of ten, a 500 after migration is one of three things. A corrupt .htaccess file, an exhausted PHP memory limit, or a plugin or theme conflict, and usually in that order. That ranking holds up in practice and lines up with both WPBeginner and WP Rocket.
Why it happens
A 500 is the server’s way of saying it tried to run your site and something stopped it cold. Vague by design. After a migration the usual suspects are a .htaccess directive the new server does not support, a PHP version mismatch, or a memory ceiling that sits lower on the new host than it did on the old one.
The fix, in order
- Rename
.htaccess. Via FTP, rename it to.htaccess_oldand reload the site. If it loads, regenerate a clean file via Settings → Permalinks → Save Changes. - Raise the PHP memory limit. Add
define( 'WP_MEMORY_LIMIT', '256M' );towp-config.php, or increase it in your host’s PHP settings. - Deactivate plugins. Rename
wp-content/pluginstoplugins_oldvia FTP. If the site recovers, rename it back and re-enable plugins one at a time to find the offender. - Check the PHP version. Match the new host’s PHP version to what your theme and plugins support.
- Read the error log. The server
error_lognames the failing file, which is the fastest route to the real cause.
Here is the habit that saves me the most time. Read the error log before you start pulling plugins one by one. More often than not it names the exact plugin or PHP function that tripped the 500. That alone turns a twenty-minute hunt into a two-minute fix.
Error establishing a database connection
WordPress cannot reach the database. Nearly every time, that is because the four credentials in wp-config.php (DB_NAME, DB_USER, DB_PASSWORD, DB_HOST) no longer match the database on the new host. This is the single most common error after a host change. I have lost count of how many times it came down to one wrong value.
Why it happens
Per Kinsta, the message shows up when the username and password in wp-config.php are wrong, or when WordPress simply cannot contact the database server at the host you named. After a migration the database name, user, and password are usually brand new. And DB_HOST is the value people miss most often.
The fix, step by step
- Open
wp-config.phpand compare all four values to the database details on the new host (database name, the user assigned to it, that user’s password, and the host). - Confirm the database user is actually assigned to the database with full privileges. Creating a user is not the same as granting it access, and this trips people up constantly.
- Set
DB_HOSTcorrectly. Kinsta notes it islocalhostroughly 90% of the time, but some hosts use127.0.0.1or a dedicated database hostname. Check your host’s documentation. - Change only the text inside the quotes. Altering anything else in those lines can break the file.
If credentials are correct
All four values right and still no joy? Then the database may be corrupted, or the server is overloaded. Add define( 'WP_ALLOW_REPAIR', true ); to wp-config.php, visit your-site.com/wp-admin/maint/repair.php to run the built-in repair, then strip the line back out. If the database server itself is down, that one is on your host. Call them.
Too many redirects (redirect loop)
A redirect loop after a move is almost always one of two things. Either the stored Site URL and WordPress URL disagree, or a forced-HTTPS rule is fighting your stored http:// URLs. The browser bounces between two addresses until it throws up its hands.
Why it happens
Per WPBeginner, mismatched WordPress Address and Site Address values cause more redirect loops than anything else. It happens constantly. A domain change, an HTTP-to-HTTPS switch, a botched search-and-replace, any of them can do it. A CDN or SSL setting that forces HTTPS while the database still holds http:// URLs produces the exact same loop.
The fix, step by step
- If you can reach the dashboard, set both URLs identically in Settings → General (same protocol, same domain, no trailing slash).
- Locked out of the dashboard? Override them in
wp-config.php. These take effect immediately and override whatever is sitting in the database.
define( 'WP_HOME', 'https://example.com' );
define( 'WP_SITEURL', 'https://example.com' );- Clear every cache there is. The caching plugin, the server cache, the CDN, the browser. A single cached redirect can leave a fixed site looking broken.
- Temporarily rename
.htaccessto rule out a redirect rule, then deactivate redirect and SSL plugins one at a time. - On Cloudflare, set SSL/TLS to Full rather than Flexible. Flexible plus a WordPress HTTPS redirect is a textbook loop.
When the redirects are the whole job
That covers the loop. A harder cousin shows up when the move forces you to build redirects from scratch, and there is no clean tooling to do it for you. On the Scattergood Foundation migration, the hardest one I have taken on, hundreds of legacy article URLs had to land somewhere sensible after the underlying relationships changed. There was no tidy old-path to new-path mapping waiting for me. I had to work it out by hand, ship a batch, watch the logs for the 404s I had missed, patch those, and go again. It took several rounds before the misses stopped. Tedious is the word. If a migration changes your category and URL structure, expect that grind rather than one perfect search-and-replace, and budget for it.
Page not found (when it is not a normal 404)
Three things tend to be behind a generic “page not found” that is not a standard 404. The new domain’s stored URLs are wrong, the homepage setting got lost in the import, or DNS has not finished pointing at the new server. Figure out which one and the fix is quick.
Why it happens
It shows up in three flavors after a move. Sometimes the whole site reads page not found because the stored Site URL still points at the old domain. Sometimes only the homepage breaks, because Settings → Reading dropped its “front page” assignment during the import. And sometimes the site just looks dead, because DNS is still resolving to the old host. Same symptom, three very different causes.
The fix, step by step
- Confirm both URLs in Settings → General match the new domain.
- Check Settings → Reading. If “Your homepage displays” is set to a static page, re-select the correct page, because the assignment can drop during import.
- Flush permalinks (Settings → Permalinks → Save Changes) so deep links resolve.
- Verify DNS has propagated to the new server. Until it does, you may see the old site, the new one, or nothing depending on your location.
- For individual pages that 404, re-check the slug and that the page status is Published, not Draft.
Images not showing after migration
When images go missing after a migration, it nearly always comes down to one of two things. The database still references the old domain, or the image files in wp-content/uploads never made the trip. Which one it is decides the fix, and you can tell them apart in about ten seconds.
Diagnose which one it is
Right-click a broken image and open it in a new tab. Does the URL still carry your old domain? Then the database needs a URL update. Is the URL correct but throwing a 404? That means the files are missing from uploads. One quick check tells you everything.
Fix one, old URLs in the database
Per Duplicator, run a search-and-replace across the database to swap the old domain for the new one. Reach for a plugin like Better Search Replace, or run the WP-CLI command that handles serialized data safely. The manual migration guide has the full walkthrough if you want it.
wp search-replace 'https://olddomain.com' 'https://newdomain.com' --skip-columns=guid --precise --dry-runRead the dry-run report first. Then re-run without --dry-run to apply it for real. Flush permalinks to finish.
Fix two, missing files
- Via FTP, open
wp-content/uploadson the new host and confirm the year/month folders and image files are actually present. If they are missing, re-upload the folder from your backup or the old server. - Set folder permissions to
755and file permissions to644so the server can serve them. - If files exist but thumbnails are broken, regenerate thumbnails with a plugin such as Regenerate Thumbnails.
If the Media Library is empty
Files present but the Media Library blank? Then the database lost its attachment records. A plugin like Media Sync rescans wp-content/uploads and rebuilds those entries. Clear all caches once it finishes.
When a page builder is the real culprit
Here is the case nobody warns you about. Sometimes the images are perfectly fine and the page builder is the one hiding them. I ran into this on a building-materials and tile store, roughly 2,000 products. Every page and post had been built in Divi, and I mean built. Completely dependent on Divi shortcodes and proprietary markup. The content was effectively jailed inside that ecosystem. So when anything moved, images and layout referenced inside those shortcodes broke in strange ways that a search-and-replace never went near. The job turned into custom parsing scripts. I processed every product, every page, every post, stripped out the Divi shortcodes and builder markup, and rebuilt it as clean, plain content. The site landed on standard WordPress with zero paid-builder dependency, every feature intact, and performance up more than 200%. The lesson stuck with me. If your broken images live inside builder shortcodes rather than the database or the uploads folder, no media plugin on earth will fix them. You have to clean the markup itself.
All-in-One WP Migration not working
When All-in-One WP Migration “is not working,” the culprit is almost always the import upload limit. Your file is bigger than the server’s allowed upload size. Or the import runs out of execution time or memory and stalls halfway through, leaving you staring at a frozen progress bar.
Why it happens
Per the plugin developer (ServMask), the upload limit you hit comes from your hosting provider’s PHP configuration, not the plugin. The free plugin imports any size your server allows. Your server is the thing capping it, not the tool. Imports also die mid-run when PHP max_execution_time or memory is set too low for a large package.
The fix, step by step
- Raise the upload limit on the server. Increase
upload_max_filesizeandpost_max_size(for example to256M) in your host’s PHP settings orphp.ini. This is the cleanest fix. - Raise execution time and memory. Increase
max_execution_timeand PHP memory so a large import can finish. - Use the official Unlimited Extension to remove the plugin’s own restore cap, which the developer recommends over editing plugin files.
When to switch tools entirely
Large site, and the import keeps dying on you? Stop fighting upload limits. Switch to a tool built for big sites. Duplicator and Migrate Guru both handle large transfers far more gracefully. The best WordPress migration plugins roundup compares your options, and the All-in-One WP Migration guide has the full upload-limit walkthrough.
Prevent these errors on your next migration
Nearly everything on this page is avoidable. You just have to know where it bites before it does. The table below maps each error to the one step that heads it off, so your next move stays clean.
| Error | Root cause | Prevention |
|---|---|---|
| 404 / page not found | Rewrite rules and permalinks did not transfer | Flush permalinks immediately after import; confirm URLs in Settings |
| Error 500 | Bad .htaccess, low memory, plugin conflict, PHP mismatch | Match PHP version on the new host; raise memory; keep a clean .htaccess |
| Database connection | Wrong DB credentials in wp-config.php | Update all four DB values and grant the user access before launch |
| Too many redirects | Mismatched site URLs or forced HTTPS | Set WP_HOME and WP_SITEURL; align SSL/CDN settings |
| Images not showing | Old URLs in DB or missing upload files | Run a serialized-safe search-replace; verify uploads transferred |
| All-in-One import stalls | Upload/restore limit, low execution time | Raise server PHP limits or use the Unlimited Extension |
Two habits prevent more pain than the rest combined. First, a serialized-safe search-and-replace for the domain change. That single pass heads off the redirect, image, and broken-link errors all at once. Second, a permalink flush the moment the import finishes, which kills the 404s before they start. Make both standard and most of this list simply never happens to you. The full process lives in the WordPress migration guide.
When to stop debugging and hand it off
Every error on this page is fixable, and you now hold the cause and the fix for each. The pattern barely changes. Confirm the stored URLs. Confirm the database credentials. Confirm the rewrite rules and file paths actually moved. Get those three right and a WordPress site comes back to life fast.
Now for the harder truth the error list above does not show you. Across the migrations I have done, moving the content was usually the easy part. Preserving the years of accumulated SEO value attached to it was the war. On Scattergood that gap was stark. The files came over fine. What nearly broke me was the taxonomy underneath them, deep and densely interconnected and many-to-many, where one publication might belong to several classifications and categories at once. Those relationships drove the URLs, so getting them wrong meant rankings quietly bleeding out through dead links. None of that shows up as a tidy 404 you can flush away in two clicks. It is the kind of damage you only catch weeks later in your search traffic, which is exactly why it is worth getting right the first time.
So here is my honest take. If your site is live, earning money, or you just do not want to be editing production files under pressure, hand the move off. A managed WordPress Migration covers a staged transfer, a full search-and-replace, redirect mapping, and post-launch QA, so these errors get caught long before a visitor ever meets one. Planning a move? Start with a free pre-migration audit to baseline your current site, then read the moving to a new host walkthrough.
Frequently asked questions
How do I fix a WordPress 404 error after migration?
Go to Settings → Permalinks and click Save Changes without altering the structure. This regenerates the rewrite rules and rebuilds .htaccess, which fixes most site-wide 404s. If it persists, rename .htaccess to .htaccess_old via FTP and save permalinks again.
What causes the 500 internal server error after migrating WordPress?
Usually a corrupt .htaccess file, an exhausted PHP memory limit, or a plugin or theme conflict, in that order. Rename .htaccess, raise the memory limit to 256M, then deactivate plugins via FTP to isolate the cause. The server error log names the failing file.
How do I fix “error establishing a database connection”?
Open wp-config.php and confirm DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST match the database on the new host. DB_HOST is usually localhost, but some hosts use 127.0.0.1 or a dedicated hostname. Make sure the user is assigned to the database.
Why does my WordPress site say too many redirects after moving it?
The stored WordPress Address and Site Address do not match, or an HTTPS rule conflicts with http:// URLs in the database. Set WP_HOME and WP_SITEURL in wp-config.php to the same correct URL, clear all caches, and align your SSL/CDN settings.
Why am I getting “page not found” after migration?
The stored site URL still points at the old domain, the homepage assignment in Settings → Reading was lost, or DNS has not finished propagating. Fix the URLs in Settings → General, re-select the front page, and flush permalinks.
Why are my images not showing after migration?
Either the database still references the old domain, or the files in wp-content/uploads did not transfer. Open a broken image in a new tab. If the URL shows the old domain, run a search-and-replace. If the file 404s, re-upload the uploads folder and set permissions to 755 and 644.
Why is All-in-One WP Migration not working or stuck on import?
Your file exceeds the server’s upload limit, or the import runs out of execution time or memory. Raise upload_max_filesize, post_max_size, max_execution_time, and PHP memory on your host, or use the official Unlimited Extension. For very large sites, switch to Duplicator or Migrate Guru.
Do I need to flush permalinks after every migration?
Yes. Flushing permalinks (Settings → Permalinks → Save Changes) after any move regenerates rewrite rules and prevents the most common 404 errors. Make it a standard step in your migration checklist.