← All guides

WooCommerce product import not working: the fixes

The Importly team · Published 2026-08-22 · Updated 2026-08-23

WooCommerce ships a decent CSV importer, but it fails in ways that look like the plugin is broken when the file is actually at fault. The import stalls at 30%, or finishes with half the products missing, or creates every variation as a standalone product.

Here is what is really going on.

The import stalls or times out

Large catalogues are the classic case. The importer works through the file in batches over repeated AJAX requests, and if your server's PHP limits cut a batch short, the whole run stops — usually with no error at all, just a progress bar that stops moving.

The fix, in order of what to try:

  1. Split the file. Two thousand rows at a time is a safe working size on shared hosting.
  2. Raise max_execution_time and memory_limit in PHP. Many hosts expose both from the control panel.
  3. If you can edit the theme's functions.php, lower the batch size:
add_filter('woocommerce_product_import_batch_size', fn () => 10);

Start with splitting the file. It solves it most of the time and costs nothing.

"A product with this SKU already exists"

SKUs are unique across a WooCommerce store. The importer refuses any row whose SKU is already taken, and reports the row as failed.

Two different situations hide behind the same message:

  • You meant to update. Then the row is fine — you just need to run the importer in update mode. On the upload screen, tick "Update existing products". Matching happens on ID first, then SKU.
  • Your file genuinely has duplicates. Very common when a supplier list repeats a reference across sheets. Deduplicate before importing.

To find them in Excel: select the SKU column, Home → Conditional Formatting → Highlight Cell Rules → Duplicate Values.

Everything lands in a single column

Your CSV is semicolon-delimited. French, German, Spanish and Italian versions of Excel write ; because the comma is the decimal mark.

The fix. WooCommerce actually handles this — you do not need to reformat. On the import screen, open the collapsed "Advanced options" and set the CSV delimiter field to ;. Alternatively, save the file as CSV UTF-8 comma-delimited.

Accented characters garbled

Café arrives as Café when the file is Windows-1252 rather than UTF-8. WooCommerce has no encoding option — the file has to be right.

The fix. In Excel, Save as → CSV UTF-8 (Comma delimited), the dedicated format entry.

Variations imported as separate products

Variable products need two kinds of row, linked together:

  • The parent: Type set to variable, with Attribute 1 name (for example Size) and Attribute 1 value(s) listing every option separated by commas (S, M, L).
  • One row per variation: Type set to variation, Parent set to the parent's SKU, and Attribute 1 value(s) holding that single variation's value (M).

Get the Parent column wrong — or leave it empty — and each variation becomes its own standalone product. Also make sure the parent row appears before its variations in the file.

Categories not created, or created flat

The Categories column uses > for hierarchy and , to separate several categories:

Furniture > Chairs, Sale

That puts the product in Chairs (nested under Furniture) and in Sale. Using / or | instead just creates one oddly-named flat category.

Prices ignored

Regular price and Sale price must be plain numbers, with a period as the decimal separator and no currency symbol. 29,90 € is not read as a price and the field ends up empty.

The fix. Format the price columns as Text and write 29.90. Reformatting how Excel displays the number is not enough — check what is actually in the saved CSV.

Images not attached

The Images column takes full public URLs, comma-separated, with the first one becoming the featured image. WooCommerce downloads and sideloads each one during the import, which is also why image-heavy files are slow. Local paths and URLs behind a login are skipped.

Pre-flight checklist

  • File under ~2,000 rows, or PHP limits raised
  • SKUs unique, or update mode enabled deliberately
  • Delimiter matched in Advanced options, or file comma-delimited
  • Saved as CSV UTF-8
  • Variation rows carry a Parent SKU, and come after their parent
  • Categories using > and ,
  • Prices as plain numbers with a period
  • Image URLs public and absolute

When it's a recurring supplier file

Setting this up once for a catalogue migration is fine.

Rebuilding it every week from a supplier's price list is where it stops being reasonable. Importly maps the supplier's columns to WooCommerce's names (Name, SKU, Regular price, Categories, Weight (kg), Stock, Images), converts prices to plain decimals, normalises weights, stock quantities and image URLs, fixes the encoding and drops empty rows. Save the mapping once as a profile and next week's file runs through the identical rules. The parent and variation rows stay your call — Importly cleans column names and values, it does not reshape the row structure.

Clean your first export free →

Set up the WooCommerce profile →

Stop reformatting exports by hand.

Try Importly free