Key takeaways

  • Almost every import failure is encoding, memory, SKU matching or a malformed row.
  • An import that stops at the same row every time has a data problem, not a server problem.
  • An import that stops at a different row every time has a server problem, not a data problem.
  • That single distinction narrows the diagnosis faster than anything else.

WooCommerce imports fail in a small number of well-defined ways. The error messages are unhelpful, which makes it feel random. It is not.

Start with the one question that splits the problem space in half: does it fail at the same row every time, or a different one? Same row means the data is bad. Different row means the server ran out of something.

1. The import stops partway with no error

Cause: PHP timeout or memory exhaustion. The AJAX request died and the browser has nothing to report.

Fix: Raise max_execution_time to 300 and memory_limit to 512M. If your host locks these, split the file into batches of 200 to 500 rows. Check the actual reason in wp-content/debug.log after enabling WP_DEBUG_LOG.

Images are usually the real culprit, because they are downloaded inside the import request. A file that fails with images will often succeed with the Images column removed, which is a quick way to confirm the diagnosis.

2. Accented characters become question marks or mojibake

Cause: The file is not UTF-8. Excel's default "CSV" export writes Windows-1252 on most Western locales.

Fix: Re-save as CSV UTF-8 in Excel, or download as CSV from Google Sheets, which is already UTF-8. If you have shell access:

iconv -f WINDOWS-1252 -t UTF-8 old.csv > new.csv

Adding a byte order mark helps WooCommerce detect the encoding rather than guess it. There is no fixing this after import short of re-importing with update-existing ticked.

3. It fails at the same row every time

Cause: That row is malformed. Nearly always an unescaped quote or a stray line break inside a field, which throws off the column count for that row.

Fix: Open the CSV in a plain text editor, not Excel, and go to that row. Look for:

  • A straight quote inside a quoted field that is not doubled. 15" screen must be written 15"" screen.
  • A hard line break inside a description field.
  • A different number of commas than the header row.

To find every row with the wrong column count at once:

awk -F',' 'NR==1{n=NF} NF!=n {print NR": "NF" fields"}' products.csv

That is naive about quoted commas, so treat it as a shortlist rather than a verdict.

4. Products imported but variations do not show

Cause: The attribute is not flagged as used for variations. This is the single most reported WooCommerce import problem.

Fix: On the parent row, the attribute's in variations flag must be 1, and its visible flag should be 1 too. Without the first, WooCommerce imports the attribute as a display-only specification. The variation rows import fine and attach to nothing, so the product renders with a spec table and no dropdowns.

Re-import with the flag set and update-existing ticked. Editing products by hand does not scale past about five. The full flag reference is in the WooCommerce CSV schema explained.

5. Duplicate products after a second import

Cause: WooCommerce could not match the incoming rows to existing products, so it created new ones.

Fix: Matching happens on ID first, then SKU. You need Update existing products ticked and a stable identifier in every row. Blank SKUs match nothing. SKUs that changed between exports match nothing.

To clean up, find duplicates by title:

SELECT post_title, COUNT(*) c
FROM wp_posts
WHERE post_type='product' AND post_status='publish'
GROUP BY post_title HAVING c > 1;

Back up before deleting anything, and check which copy carries the images and reviews.

6. Images did not import

Cause: Four possibilities, in order of likelihood.

  1. Timeout. Downloads exceeded the request budget. Smaller batches.
  2. Hotlink protection. The source blocks requests without a matching referer, so WooCommerce receives a 403.
  3. Relative URLs. /wp-content/uploads/tee.jpg is skipped. Needs the full https:// form.
  4. Source is already offline. Nothing to fetch.

Fix: Test a URL with curl -I from the destination server, not from your laptop. A 200 from your browser and a 403 from the server is the classic hotlink signature.

Do not decommission the source until images are confirmed. WooCommerce does not retry later. Once the source domain is gone, those images are unrecoverable except from a backup.

7. Prices all imported as zero

Cause: The price column contained something that is not a bare decimal, or it was mapped to the wrong field.

Fix: Strip currency symbols, thousands separators and spaces. Convert comma decimals to full stops: 1.299,00 from a European locale must become 1299.00. Also confirm on the mapping screen that your column went to Regular price and not Sale price, which is a surprisingly easy misclick.

8. Products import but do not appear on the shop page

Cause: Usually Published or Visibility in catalog.

Fix: Published takes 1 for published, 0 for private, and -1 for draft. Zero is the trap: private products are published but visible only to admins, so the store looks empty while wp-admin shows everything present. Also check Visibility in catalog is visible and not search or hidden.

9. Categories duplicated with slight variations

Cause: Inconsistent whitespace around the > separator, or trailing spaces.

Fix: Normalise before import. In a spreadsheet, TRIM() the column and standardise on Parent > Child with exactly one space either side. Merge the duplicates afterwards under Products, Categories.

10. "Invalid file type" on upload

Cause: WooCommerce checks MIME type, not just the extension. Files saved as .csv by some tools carry a MIME type WordPress rejects.

Fix: Open and re-save through a plain spreadsheet application or a text editor. If it persists, upload to wp-content/uploads/ via FTP and use the "or enter the path to an existing file on the server" option on the import screen, which skips the upload check entirely.

11. Import completes but the count is wrong

Cause: Rows were skipped silently. Blank SKU on a row where a SKU is expected, a missing Type, or a variation whose Parent does not resolve.

Fix: The importer shows a "skipped" count on the results screen that is easy to miss. Check it. Then confirm that every variation's Parent value exactly matches an existing parent SKU, including case, and that parents appear before their variations in the file.

12. The site is slow after a large import

Cause: WooCommerce's lookup tables and term counts are stale, and thumbnails may not exist.

Fix: Run these in order:

wp wc update
wp term recount product_cat product_tag
wp media regenerate --yes

Then in the admin, WooCommerce, Status, Tools, and run Regenerate product attributes lookup table. Skipping that one makes filtered navigation and attribute-based sorting return wrong results, which is a bug report you will otherwise receive from a customer.

Or stop debugging CSVs entirely

Our free WordPress plugin reads a live Scrapify feed and handles encoding, batching, retries and image fetching for you. No file to malform.

See how it works Ask us for help

A pre-import checklist

Ten minutes here saves a day of the above:

  • File saved as UTF-8.
  • Every row has the same column count as the header.
  • Every product has a unique, stable SKU.
  • Prices are bare decimals with a full stop.
  • Image URLs are absolute and return 200 from the destination server.
  • Parents sorted before variations.
  • Attribute in-variations flags set on every variable parent.
  • Published is 1 or -1, never 0 unless you mean private.
  • Tested on a 5 row file first.
  • Full database backup taken.

That last one is not optional. Imports with update-existing ticked can overwrite good data with bad across the entire catalogue, and there is no undo.

Frequently asked questions

Why do accented characters turn into question marks after import?
The file is not UTF-8, or it is UTF-8 without a byte order mark and something along the way guessed Windows-1252. Re-save the CSV as UTF-8 with BOM. In Excel that is Save As, CSV UTF-8. In Google Sheets, download as CSV, which is already UTF-8.
Why does my import stop at the same row every time?
That row contains something the importer chokes on: usually an unescaped quote breaking the column count, or an image URL that hangs. Open the CSV in a plain text editor, go to that row, and check the quoting. A row with a different number of columns than the header will reliably halt the run.
My variations imported but the product shows no options. Why?
The attribute exists but is not marked as used for variations. In the CSV the parent row needs the attribute's in-variations flag set to 1. Without it WooCommerce creates the attribute as a display-only spec and the variation rows attach to nothing.
How do I raise the WooCommerce import limits?
Increase PHP memory_limit to 256M or more, max_execution_time to 300, and both upload_max_filesize and post_max_size above your file size. On managed hosting these are often locked, in which case splitting the file into smaller batches is the only route.

Keep reading

WooCommerce The WooCommerce Product CSV Schema Explained, Field by Field WooCommerce How to Bulk Import Products into WooCommerce Without a Spreadsheet WooCommerce How to Export All WooCommerce Products to CSV: 5 Methods Compared