You hit ”
Import Demo Content" on a fresh WordPress install, and the progress bar has been stuck at 64% for twenty minutes. Or worse, it immediately barfed an "Import Failed (HTTP 500)" modal with zero context about what broke.I’ve lost count of how many times I’ve hit this wall across shared cPanel hosts, VPS boxes, and cloud setups. The flashy one-click setup wizards bundled with Themeforest and commercial themes are notoriously fragile. Here’s how to trace the exact failure in DevTools and your server logs, bump your PHP resource ceilings, clear network bottlenecks, and get the demo imported properly.

Inspect Network Traffic and Server Logs First
Most modern themes use an AJAX or REST API worker to batch-import media, register custom post types, and map out navigation menus. When the importer stalls, your browser usually knows the exact reason before the UI admits anything went wrong.
Pop open DevTools in Chrome or Firefox (F12 or Cmd + Option + I). Switch to the Network tab, filter by Fetch/XHR, and kick off the
Keep your eyes peeled for calls to admin-ajax.php or endpoints under /wp-json/ that return red status codes:
- 504 Gateway Timeout: Nginx or Apache cut the connection because the PHP worker took too long to finish.
- 500 Internal Server Error: PHP crashed hard—almost always hitting an out-of-memory error or an unhandled timeout deep inside a parsing function.
- 403 Forbidden: ModSecurity or an overzealous security plugin saw incoming XML or JSON payloads and flagged them as malicious.
- Failed / CORS / Net::ERR_CONNECTION_RESET: The PHP process died abruptly, usually killed by the system OOM (Out Of Memory) killer.
To see what’s actually hiding behind that 500 error, turn on WordPress debugging. Jump in via SSH or SFTP, open wp-config.php, and replace the basic debug definition with this:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
@ini_set('display_errors', 0);Trigger the import again, then tail /wp-content/debug.log. Almost every single time, you’ll catch one of these two culprits sitting right at the bottom:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20971520 bytes)
PHP Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/html/wp-includes/class-wp-http-curl.phpIf you see either of those, your host’s default resource limits are strangling the process.
Raise PHP Memory, Execution Time, and Upload Caps
Most default host configurations give PHP 128MB of RAM and 30 seconds of execution time. That’s fine for running a lightweight blog, but a modern theme demo packed with WooCommerce products, high-res stock photos, and bloated page builder layouts will chew through those limits in seconds.
Here are the minimum numbers I configure before running any hefty demo import:
memory_limit: 512Mmax_execution_time: 300 (bump to 600 if it’s a massive store catalog)upload_max_filesize: 64Mpost_max_size: 64Mmax_input_vars: 3000
Depending on your server stack, bump these values using one of the three methods below.
Method 1: Update .htaccess (Apache / LiteSpeed)
If you’re running Apache or LiteSpeed with mod_php, drop these lines near the top of your root .htaccess file, right above the # BEGIN WordPress block:
php_value memory_limit 512M
php_value max_execution_time 300
php_value max_input_time 300
php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_input_vars 3000Warning: If saving this throws an immediate 500 Internal Server Error across your whole site, your server is running PHP via PHP-FPM or suPHP. Revert the file immediately and use Method 2 or 3 instead.
Method 2: Edit php.ini or .user.ini
If your host uses PHP-FPM (standard on most modern hosts), create or open a .user.ini file directly in your WordPress root directory (next to wp-config.php):
memory_limit = 512M
max_execution_time = 300
max_input_time = 300
upload_max_filesize = 64M
post_max_size = 64M
max_input_vars = 3000If you’re managing your own VPS, modify the active php.ini directly. Check the PHP runtime configuration documentation if you need syntax specifics for your build. Don’t forget to reload your PHP-FPM service afterward:
sudo systemctl restart php8.2-fpmMethod 3: Configure wp-config.php
WordPress sets its own internal memory cap that overrides your server’s base settings unless you tell it otherwise. Even if your server allows 512M, WordPress caps itself to 40MB by default (64MB on multisite).
Open wp-config.php and add these definitions right above the /* That's all, stop editing! Happy publishing. */ line:
define('WP_MEMORY_LIMIT', '512M');
define('WP_MAX_MEMORY_LIMIT', '512M');
@ini_set('max_execution_time', '300');Verify that your changes took by heading to Tools → Site Health → Info → Server in your WordPress dashboard. Check that both the memory limit and PHP execution time reflect your new numbers.
If you run into file size ceilings while uploading zipped demo bundles manually, take a look at our walkthrough on how to fix 413 Request Entity Too Large on Hostinger WordPress.
Fix cURL Error 28 and Remote Asset Connection Timeouts
Theme demo packages don’t bundle hundreds of megabytes of media files inside the theme zip. Instead, they ship with an XML file containing remote image URLs. As the importer runs, WordPress connects to an external Amazon S3, Cloudflare R2, or private demo server to grab every single image.
If your server can’t establish that outbound connection, the process will spin until it crashes with a cURL timeout:
cURL error 28: Operation timed out after 30001 milliseconds with 0 bytes receivedLog in over SSH and test whether your host can even reach outbound endpoints using cURL:
curl -Iv https://raw.githubusercontent.com
curl -Iv https://wordpress.orgIf that command hangs or errors out, you’re usually facing one of three issues:
- Locked-Down Outbound Firewall: Some hardened servers or custom UFW rules block outbound requests on ports 80 and 443 for web worker users. Make sure your server’s outbound firewall allows HTTP/HTTPS traffic.
- Missing cURL or allow_url_fopen: Double-check that
allow_url_fopen = Onin yourphp.iniand verify that PHP’s cURL extension is active withphp -m | grep -i curl. - The Author’s Demo Server Is Down: Sometimes the theme author’s asset bucket is offline or rate-limiting your server’s IP address. Grab the asset URL from DevTools and paste it directly into your local browser to see if it loads. If you picked up the theme from a marketplace, check out our guide on how to vet a WordPress theme on ThemeForest to make sure the developer actually maintains their infrastructure.
Clean Up Orphaned Database Tables Before Retrying
A failed
import leaves behind a mess: half-created posts, empty taxonomy terms, broken menus, and partial Elementor revisions. If you just re-run the importer on top of that rubble, it'll either duplicate every page (hello, "Home - Copy 2") or choke on duplicate slug collisions.If this is a fresh build with nothing you need to save, wipe the database clean before running the import again.
If you have WP-CLI access, this takes about three seconds from the command line:
wp db reset --yes
wp core install --url="https://example.com" --title="My Site" --admin_user="admin" --admin_password="YourStrongPassHere" --admin_email="dev@example.com"You can find more commands and options in the official WP-CLI handbook.
If you don’t have SSH access, install the WP Reset plugin. Head over to Tools → WP Reset, scroll down to “Site Reset”, type reset, and confirm. It flushes all posts, custom tables, and options without touching your theme or plugin files on disk.
Run the Import Manually via Native WordPress Tools
When a theme’s proprietary AJAX wizard keeps crashing no matter what you tweak, skip it. Almost every premium theme includes raw demo export files inside the main package download.
Make sure your theme archive was extracted properly to begin with—if you ran into path issues earlier, check our guide to fix the theme is missing the style.css stylesheet error.
Extract the full theme package on your machine and dig around for a folder named /demo-data/, /dummy-data/, or /sample-content/. You should see:
content.xml(posts, pages, menus, metadata)widgets.wieorwidgets.json(sidebar and footer setups)customizer.dat(typography, colors, Customizer settings)revslider.zip(Slider Revolution exports, if used)
Import them sequentially using native tools:
- Install the native importer via Tools → Import → WordPress → Install Now → Run Importer.
- Upload your
content.xmlfile. Map the content authors to your admin user, check “Download and import file attachments”, and submit. - If your connection is slow or media downloads keep stalling, uncheck “Download attachments”. You won’t get placeholder photos, but your pages, shortcodes, and layouts will import cleanly in about five seconds.
- For widgets, install the free Widget Importer & Exporter plugin, head to Tools → Widget Importer & Exporter, and upload the
.wiefile. - For Customizer values, use the Customizer Export/Import plugin to load the
.datfile.
Going this route bypasses the fragile client-side AJAX loop entirely.
Disable Page Builder Caches and Conflicting Plugins
Elementor and WPBakery run asset compilers and JSON validators every time a layout writes to the database. If your theme importer tries to inject forty complex pages while Elementor is actively regenerating CSS and parsing components in the background, your memory usage will spike through the roof.
A few quick precautions before hitting import:
- Turn off caching plugins: Temporarily disable WP Rocket, LiteSpeed Cache, W3 Total Cache, or server-level Redis object caching. Stale queries during an import create bizarre duplicate entries.
- Pause security suites: Shut off Wordfence, Sucuri, or Cloudflare’s “Under Attack Mode”. Repeated rapid-fire POST requests to
admin-ajax.phplook like a brute-force attack to an active firewall, and it will block your IP mid-import. - Regenerate builder files: If your pages import but look completely broken, go to Elementor → Tools → General → Regenerate Files & Data. If you hit editor stalls after finishing the import, see how to fix Elementor preview could not be loaded errors.
Frequently Asked Questions
Why does my demo import freeze at 99% every time?
At 99%, the importer has usually finished pulling raw content and is running heavy cleanup routines: thumbnail regeneration, taxonomy hierarchy mapping, and menu location binding. This puts intense load on MySQL. If your database runs out of connection buffers or hits a query timeout, the process silently hangs. Bump PHP’s max_execution_time to 600 and check MySQL’s wait_timeout value to get past that final stretch.
Can I import demo data on an established, live site?
You can, but I really wouldn’t. Importers love to overwrite your static homepage settings, reset navigation menus, and scramble Customizer variables. If you absolutely have to do it on a live project, pull a complete backup of both your database and wp-content folder first—or do the import on a staging clone.
What should I do if images are missing after the import finishes?
That’s often intentional. Many theme developers license commercial stock photography for their live demos but don’t have redistribution rights. When they package the demo for export, they replace images with blank gray placeholders. Check the theme’s documentation to see if stock imagery is actually included.
Will increasing PHP limits on shared hosting actually work?
Not always. Shared hosts frequently enforce hard limits via CloudLinux LVE at the operating system level. Even if your php.ini claims memory_limit = 512M, the server might kill your process the moment it crosses 256MB. Check your cPanel “Resource Usage” dashboard to see if you’re hitting physical CPU or memory ceilings.
Next Steps for Your Fresh WordPress Build
Once the demo finishes importing, jump into your plugins list immediately. Demo wizards are infamous for installing bloatware you’ll never touch—extra slider engines, duplicate contact form plugins, and third-party newsletter addons. Deactivate and delete anything your project doesn’t actually need before building out the rest of your site.

