WordPress Import Stuck or Failing? Fix XML Timeouts
You export a WordPress site as an XML file, hit "Upload file and import" on the new site, and the progress bar just... stops. Or it fails outright with a white screen. If you've ever watched a WXR import die at "Importing attachment 47 of 900," this one's for you.
Symptom
A few ways this shows up, depending on where it breaks:
- The importer freezes partway through with no error, and refreshing shows a half-finished import.
- You get a blank white screen or a 500 error mid-import.
- Posts and pages import fine, but almost every featured image and inline attachment fails with "Failed to import Media."
- The upload itself is rejected before the import even starts: "The uploaded file exceeds the upload_max_filesize directive."
- WP-CLI import runs but silently drops content past a certain point with no visible error in the terminal.
Why It Happens
The WordPress Importer (and the WXR format it reads) was built for a web request that finishes in a few seconds. A real export with hundreds of posts and thousands of images asks it to do far more than that in a single PHP process. A handful of server limits get hit, usually in this order:
1. Upload size limit
Your export file is bigger than upload_max_filesize or post_max_size. On shared cPanel hosting these often default to 64M or lower, and a five-year-old blog's export can easily clear that.
2. Execution timeout
Apache/PHP-FPM cuts the request off after max_execution_time (commonly 30s on shared plans). Downloading and inserting hundreds of attachments one by one blows past that easily, even though each individual insert is fast.
3. Memory exhaustion
Every post, term, and attachment record gets built up in PHP memory before it's written. On a default 256M WordPress memory limit, a large export with lots of custom fields or serialized meta can exceed it, throwing a fatal error mid-batch.
4. Attachments fetched over HTTP, not from disk
This is the one people miss. The importer doesn't copy image files from the old export — it re-downloads every attachment from its original URL on the source site. If the old site is offline, slow, rate-limiting, or blocked by your host's outbound firewall, every image import fails or times out, even though the text content came through fine.
Fix 1: Raise the PHP Limits (Fastest Path)
On Getwebup cPanel hosting, go to MultiPHP INI Editor and set:
upload_max_filesize = 256M
post_max_size = 256M
max_execution_time = 300
max_input_time = 300
memory_limit = 512M
If you're on a VPS running PHP-FPM directly, edit the pool's php.ini (usually /etc/php/8.2/fpm/php.ini) with the same values, then:
sudo systemctl restart php8.2-fpm
sudo systemctl restart nginx # or apache2
Also bump WP_MEMORY_LIMIT in wp-config.php if the site-level limit is lower than the server's:
define( 'WP_MEMORY_LIMIT', '512M' );
This alone fixes most stalls under a few thousand posts. If it's still timing out, move to WP-CLI — it isn't bound by the web server's request timeout at all.
Fix 2: Import via WP-CLI Instead of the Browser
If you have SSH access (Getwebup VPS plans, or cPanel Terminal), this is the more reliable route for anything over a few hundred posts. First install the importer command:
wp plugin install wordpress-importer --activate
Then run the import with a generous PHP time limit for the CLI process only — this doesn't touch your web-facing php.ini:
php -d max_execution_time=0 -d memory_limit=1024M $(which wp) import export.xml --authors=create
Because it runs in the terminal, there's no 30-second web request ceiling to fight. A 2,000-post export that stalls forever in the browser typically finishes via WP-CLI in a few minutes.
Fix 3: Split a Huge WXR File
Past roughly 2,000 posts or a 500MB export, even WP-CLI starts to strain. Split the export first:
- Install the WXR File Splitter plugin on the source site before exporting, and export in batches of 500 posts.
- Or use WordPress's built-in export filters — Tools → Export lets you export by post type and date range, so you can pull "Posts, 2020-2022," then "Posts, 2023-2024," separately.
Import each file in sequence rather than one massive file in one pass.
Fix 4: Attachments Failing to Import
If posts and pages come through but images don't:
- Confirm the source site is actually reachable —
curl -I https://old-site.com/wp-content/uploads/2023/01/image.jpgfrom your new server should return200 OK, not a timeout or DNS failure. - Check
allow_url_fopenis on (php -i | grep allow_url_fopen) — the importer needs it to fetch remote files. - If the old host blocks hotlinking or bot user agents, temporarily disable hotlink protection on the source site during the import window.
- As a fallback, skip remote fetching entirely: copy the
wp-content/uploadsfolder directly via SFTP or the cPanel File Manager, then runwp media regenerateto rebuild thumbnail sizes and reconnect attachment metadata.
Prevention
| Setting | Safe default for imports | Where to set it |
|---|---|---|
| upload_max_filesize | 256M | MultiPHP INI Editor / php.ini |
| post_max_size | 256M | MultiPHP INI Editor / php.ini |
| max_execution_time | 300 (or 0 for CLI) | MultiPHP INI Editor / php.ini |
| memory_limit | 512M | php.ini + wp-config.php |
| Import method | WP-CLI over SSH | N/A |
For anything you plan to migrate regularly — staging pushes, client handoffs — skip the XML importer altogether and use a full-site tool like Duplicator or a database + files copy. WXR is fine for content-only moves, but it was never meant to be a general migration format.
When to Just Call Support
If you've raised every limit above and the import still dies at the exact same post or attachment every time, that's usually not a resource problem — it's a corrupted or malformed WXR file (often from a partial export). Re-export from the source, or open a ticket with the export file attached so we can check it for broken XML entities before you burn another hour on retries.
Frequently asked questions
Why does my WordPress import stop at a specific attachment every time?
The importer fetches each attachment over HTTP from its original URL on the source site rather than reading a local file. If that URL is slow, offline, or blocked, the import stalls or fails right there. Confirm the source site is reachable with curl -I before retrying, or copy the uploads folder directly and skip remote fetching.
Is WP-CLI import faster than the browser importer?
It is not necessarily faster per record, but it is not bound by the web server's request timeout, so it can finish imports that the browser-based importer would never complete. For anything over a few hundred posts, use WP-CLI over SSH.
What is a safe upload_max_filesize for a WordPress export?
For most site exports, 256M is enough headroom. If your export is still larger than that, split it into smaller WXR files by date range or post type before importing rather than raising limits indefinitely.
Should I use the XML importer for a full site migration?
No. WXR only carries posts, pages, comments, and terms - it does not move plugins, themes, widgets, or settings. For a full site move, use a migration plugin like Duplicator or a direct database and files copy, and save the XML importer for content-only transfers.
My images imported but show broken thumbnails - why?
This usually means the full-size file came through but WordPress never regenerated its thumbnail sizes. Run wp media regenerate over SSH to rebuild every image size from the originals.