Duplicator Plugin Migration Errors: Causes and Fixes
You installed Duplicator (or a similar all-in-one migration plugin), built a package, and now it's stuck - "Package Build Failed," a blank installer.php, or a database error right after import. Here's what actually causes each failure and how to get the migration moving again.
Why People Reach for a Migration Plugin
Most guides for moving WordPress to a new host - including our own zero-downtime DNS cutover guide - assume you're comfortable with SFTP, phpMyAdmin exports, and editing wp-config.php by hand. A migration plugin like Duplicator, All-in-One WP Migration, or UpdraftPlus's migration mode skips that: it bundles your files and database into one package, then unpacks it on the new server with a browser-based installer. It's faster for small-to-medium sites and doesn't require SSH access.
The trade-off is that when it breaks, the error messages point at the plugin's internals instead of the underlying server limit that actually caused the problem. That's the gap this post fills.
"Package Build Failed" or the Build Hangs Forever
Symptom: You click "Build," the progress bar creeps along, and then either it times out with a generic build error or the browser tab just spins with no error at all.
Cause: Building the package means zipping your entire wp-content folder plus a full database dump, in one PHP process, within your host's execution limits. Three things commonly blow that budget:
- A large media library (thousands of images, or a few gigabytes of video/PDF uploads)
- A bloated database - old post revisions, spam comments, orphaned transients
max_execution_timeormemory_limitset too low for a single long-running PHP request
Fix:
- Clean the database first. In WP-CLI:
wp transient delete --allandwp post delete $(wp post list --post_type='revision' --format=ids)to clear revisions. - Raise PHP limits temporarily via cPanel's MultiPHP INI Editor, or add to
wp-config.php:define('WP_MEMORY_LIMIT', '512M'); set_time_limit(300); - Exclude large, non-essential folders (cache directories, old backup zips already sitting in
uploads) from the package before building. - If the media library itself is the bulk of the size, upload it separately over SFTP once the site is live, instead of forcing it through the plugin's build process.
installer.php Returns a 403 or a Blank Page
Symptom: You've uploaded and extracted the package on the new host, you browse to yourdomain.com/installer.php, and you get a 403 Forbidden or a completely blank white page.
Cause: Two different culprits produce the same symptom:
- 403: A leftover
.htaccessfrom the old site (part of the extracted package) contains rules - directory listing denies, IP restrictions, or a security plugin's hardening rules - that don't apply on the new server, or ModSecurity on the new host is flagging the installer script itself as suspicious. - Blank page: A PHP fatal error is happening but
display_errorsis off, so nothing renders. This is almost always a PHP version mismatch - the old site ran PHP 7.4 with an old plugin, the new host defaults to PHP 8.2.
Fix: For the 403, temporarily rename the extracted .htaccess to .htaccess.bak via File Manager, run the installer, then restore a fresh one afterward. For the blank page, check the PHP error log path in cPanel (Metrics > Errors) or set PHP version to match the old server first via MultiPHP Manager, then retry.
Import Stuck on "Extracting Archive" or "Scanning"
Symptom: The installer gets partway through - archive extraction or the pre-flight scan step - and just stops, no error, no progress.
Cause: Usually one of:
| Cause | How to confirm |
|---|---|
| Destination account is out of disk quota | cPanel > Statistics sidebar shows disk usage near 100% |
PHP's ZipArchive extension isn't enabled | Check phpinfo() or MultiPHP INI Editor for the Zip module |
| Upload was interrupted or corrupted (large file over a flaky connection) | File size on the new server doesn't match the original zip |
Fix: Clear space first if quota is the issue (check cPanel Disk Usage for old leftover backups). If Zip isn't enabled, most cPanel hosts let you switch it on per-domain in MultiPHP INI Editor - contact support if it's greyed out. For a corrupted upload, skip the browser upload entirely and push the file over SFTP or cPanel's File Manager "Upload," which handles large files more reliably than a plugin's internal uploader.
Database Error or White Screen Right After Import
Symptom: The installer says "Success," but the live site now shows "Error establishing a database connection," or loads as a blank white page.
Cause: Duplicator's installer asks you to confirm database name, user, and host during setup - this step is where migrations quietly fail:
- You typed the new database credentials but left the table prefix mismatched against what's actually in the dumped SQL
- The new cPanel account auto-prefixes database and user names (
cpuser_dbname) differently than the old host did, and the installer didn't rewrite every reference - The database host isn't
localhoston the new server (rare, but happens on some VPS setups with a remote DB)
Fix: Open wp-config.php directly in File Manager and confirm DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST match exactly what you created in the MySQL Database Wizard - not what the old config had. If the site loads but links, images, or the admin still point at the old domain, run a search-replace to fix serialized URLs:
wp search-replace 'https://olddomain.com' 'https://newdomain.com' --skip-columns=guid --all-tables
Don't run a plain SQL find-and-replace for URLs - WordPress serializes arrays in the database, and a raw text replace corrupts the string length prefix, breaking widgets and theme settings silently.
Prevention: What to Do Differently Next Time
- Clean revisions, transients, and spam comments before building the package, not after it fails.
- Check the new host's PHP version and match it before you start, not after the installer breaks.
- For sites over ~2 GB, migrate the media library separately via SFTP instead of forcing it into one archive.
- Always test the site on a staging URL or the server's temporary IP before pointing DNS at it, so a broken migration doesn't take the live site down.
- Keep the old site untouched and live until the new one is fully verified - don't delete the source until you've checked every page, form, and the admin login on the destination.
When to Just Ask Support Instead
If you're moving to Getwebup and the package build keeps failing on a large site, it's usually faster to have us do a direct server-to-server transfer than to keep fighting PHP limits in a browser-based plugin. Open a support ticket with your current host's cPanel or SSH access details and we can pull the site across directly - no zip file, no upload limit, no installer.php.
Frequently asked questions
Why does Duplicator say "Package Build Failed" with no other details?
It almost always means PHP hit its memory_limit or max_execution_time while zipping your files and dumping the database in one request. Clean up old revisions and transients, raise the PHP memory limit temporarily, and exclude large non-essential folders from the package before rebuilding.
Is it safe to delete the old site right after the migration installer says "Success"?
No. Keep the old site live and untouched until you have manually checked the new site - homepage, a few inner pages, contact forms, and the wp-admin login - and confirmed DNS has fully switched over. A successful installer message only means the files extracted; it does not guarantee the site works.
My site loads after migration but images and links still point to the old domain. What do I do?
Run a WP-CLI search-replace instead of editing the database by hand: wp search-replace https://olddomain.com https://newdomain.com --skip-columns=guid --all-tables. A raw SQL text replace will corrupt WordPress's serialized data and break widgets or theme settings.
Should I use a migration plugin or a manual SFTP/phpMyAdmin transfer?
Plugins like Duplicator are faster for small-to-medium sites without SSH access. For sites over roughly 2 GB, or when you have SSH access on both ends, a manual or server-to-server transfer is more reliable since it is not limited by a single PHP process building one big archive.