SYSTEMS OPERATIONAL
WordPress

WordPress Import Stuck or Failing? Fix XML Timeouts

Getwebup 5 min read

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:

  1. Confirm the source site is actually reachable — curl -I https://old-site.com/wp-content/uploads/2023/01/image.jpg from your new server should return 200 OK, not a timeout or DNS failure.
  2. Check allow_url_fopen is on (php -i | grep allow_url_fopen) — the importer needs it to fetch remote files.
  3. If the old host blocks hotlinking or bot user agents, temporarily disable hotlink protection on the source site during the import window.
  4. As a fallback, skip remote fetching entirely: copy the wp-content/uploads folder directly via SFTP or the cPanel File Manager, then run wp media regenerate to rebuild thumbnail sizes and reconnect attachment metadata.

Prevention

SettingSafe default for importsWhere to set it
upload_max_filesize256MMultiPHP INI Editor / php.ini
post_max_size256MMultiPHP INI Editor / php.ini
max_execution_time300 (or 0 for CLI)MultiPHP INI Editor / php.ini
memory_limit512Mphp.ini + wp-config.php
Import methodWP-CLI over SSHN/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.

#wordpress #xml-import #wxr #wp-cli #content-migration #timeout

Keep reading

Chat with Support