Navigated to blog › woocommerce-csv-import-errors
Back to Blog
crm-import-guides

WooCommerce CSV Import: Fix Product and Variation Errors (2026)

March 21, 2026
15
By SplitForge Team

Quick Answer

WooCommerce CSV product imports fail for a predictable set of reasons: missing Product Name (the only required column), duplicate SKU values, image URLs that are inaccessible or relative paths instead of full URLs, currency symbols in the price column, and incorrect variable product row structure.

Why it happens: WooCommerce's built-in CSV importer validates specific field constraints before creating product records. Some failures are hard errors (the row is rejected); others are silent drops (the row imports but with blank fields).

The fix: Validate your product CSV before importing — check for duplicate SKUs, missing names, price formatting, and image URL accessibility before you hit upload.

Root cause: Price column formatting (currency symbols, commas in numbers) and duplicate SKUs are among the most common causes of WooCommerce import failures in files migrated from other platforms.


Fast Fix (90 Seconds)

If your WooCommerce import just failed or products arrived with blank fields, try this first:

  1. Check the Name column — Every row must have a product name. Rows with a blank Name are skipped silently.
  2. Check for duplicate SKUs — Open your CSV, filter the SKU column, and check for values that appear more than once. Duplicate SKUs cause row rejection.
  3. Check the Regular Price column — Remove all currency symbols ($, , £) and comma thousands separators. Price must be a plain decimal number: 29.99, not $29.99 or 29,99.
  4. Check image URLs — All image values must be full URLs starting with https://. Relative paths like /images/product.jpg fail.
  5. Re-import the corrected file — Use WooCommerce's "Update existing products" option to avoid creating duplicates for rows that partially succeeded.

If you're importing variable products and all variations are failing, continue below for the variable product structure section.


Minimum Valid WooCommerce Product CSV

The smallest CSV that WooCommerce's built-in importer will accept without errors. Use this as your base template before adding optional columns.

Name,SKU,Regular price,Type
Blue Widget,WIDGET-001,29.99,simple
Red Widget,WIDGET-002,19.99,simple

Required column: Name only. All other columns are optional. Rules for the four most important columns:

ColumnRequiredFormatCommon mistake
Name✅ YesAny text stringBlank = row silently skipped
SKUNoAlphanumeric, uniqueDuplicate = "Skipping row, SKU already exists"
Regular priceNoPlain decimal: 29.99Currency symbol = blank price
TypeNosimple / variable / grouped / external (lowercase)Capitalized = invalid product type

Add columns from WooCommerce's full CSV schema as needed. Every column beyond these four is optional and can be left out until your data is validated.


TL;DR: WooCommerce product import failures trace most often to price formatting (remove currency symbols), duplicate SKUs (each must be unique), and image URL format (full https:// URLs only). Run your file through Data Validator to catch all three before the upload attempt — everything validates in your browser.


Your WooCommerce store migration is almost complete. You've exported 2,400 products from your old platform, mapped the columns to WooCommerce format, and started the import. It completes — and 847 products are missing from your catalog. The rest imported, but some have blank prices, missing images, or wrong category paths.

WooCommerce's built-in importer (introduced in WC 3.1) has two distinct failure modes: rows that are skipped entirely during import, and rows that import but with field data silently dropped. Both produce the same symptom — incomplete catalog — but require different fixes.

Product CSV files often contain pricing, inventory levels, category structures, and image paths. When you use a cloud-based CSV validation or cleaning tool, you're uploading your entire product catalog — including pricing strategy and inventory data — to a remote server before you've even confirmed the file is correct. SplitForge validates in Web Worker threads running entirely in your browser. Nothing is transmitted to any server. You can verify this in Chrome DevTools Network tab while validation runs.

Each error type in this guide was reproduced using the WooCommerce built-in CSV importer on WooCommerce 8.x, March 2026. For the complete e-commerce and CRM import failure taxonomy, see our CRM import failures complete guide. If your store runs Shopify, see Shopify CSV Import Errors. For pre-import data cleaning rather than error fixing, see Clean Product Catalog CSVs for Shopify and WooCommerce.


What WooCommerce's Import Errors Actually Mean

"Skipping row, SKU already exists" — A SKU value in your CSV matches a product already in your WooCommerce store. WooCommerce won't create a second product with the same SKU unless you've selected "Update existing products" in import settings.

Product row imported but price is blank (no error) — The Regular Price column contained a currency symbol, comma, or other non-numeric character. WooCommerce silently drops the value rather than rejecting the row.

Product imported but images are missing (no error) — The Image column contained a relative URL, a local file path, or a URL that returned an error when WooCommerce attempted to fetch it.

"Invalid product type" — The Type column contains a value not in WooCommerce's accepted set: simple, variable, grouped, or external.

Variation rows ignored on variable products (no error) — The parent product row and variation rows are not correctly linked, or the variation rows are missing required attribute columns.


Error / SymptomRoot CauseFix
Row skipped, SKU already existsSKU matches an existing productUse "Update existing products" or deduplicate SKUs
Price blank after importCurrency symbol or comma in price columnUse plain decimal: 29.99 not $29.99 or 29,99
Images missing after importRelative URL or inaccessible image URLUse full https:// URLs; verify URLs are publicly accessible
"Invalid product type"Type value not in accepted setUse: simple, variable, grouped, or external
Variations not createdVariable product structure incorrectParent row + variation rows; attributes must be defined
Category blank after importCategory path uses wrong separator or doesn't existUse > for hierarchy: Clothing > Shirts

Table of Contents


This guide is for: WooCommerce store owners, catalog managers, and developers importing product data via CSV.

Already know your error type? Jump to the fix using the ToC above.


Why WooCommerce Import Has Two Failure Modes

WooCommerce's CSV importer processes each row through two validation layers. The first layer checks hard constraints: does the SKU already exist, is the product type valid, are required columns present. Rows that fail here are skipped and counted in the import summary.

The second layer handles field-level data. This layer accepts the row but silently drops values that don't match the expected format — price with a currency symbol, image with a relative path, category with a wrong separator. There's no error count for these; the product lands in your catalog with blank fields.

The import summary screen reports both "Products imported" and "Products skipped" — but it has no count for "Products imported with blank fields." That's the harder failure to catch.

What a WooCommerce Import Failure Looks Like Before Cleanup

❌ BROKEN — WooCommerce product CSV with common failure patterns:

ID,Name,SKU,Regular price,Categories,Images,Stock,Type
,Blue Widget,WIDGET-001,$29.99,Widgets,images/blue-widget.jpg,50,simple
,Red Widget,WIDGET-001,29.99,Widgets > Colors,,100,simple
,,,15.00,Accessories,https://yourstore.com/img/item.jpg,25,simple
,Green Widget,WIDGET-003,29.99,Widgets,https://yourstore.com/img/green.jpg,-5,simple
,Purple Widget,WIDGET-004,29,99,Gadgets,https://yourstore.com/img/purple.jpg,10,Simple

Import results:
Row 1: Price "$29.99" — currency symbol causes price to import as blank
Row 2: SKU "WIDGET-001" duplicates Row 1 — "Skipping row, SKU already exists" if WIDGET-001 was created
Row 2: No image URL — image blank after import
Row 3: Name is empty — row skipped silently
Row 4: Stock "-5" — negative stock values are accepted if "Allow backorders" is enabled in WooCommerce settings; rejected or set to 0 if backorders are disabled
Row 5: Price "29,99" — comma as decimal separator; price imports as blank
Row 5: Type "Simple" — capitalized; should be lowercase "simple"

FIXED:
ID,Name,SKU,Regular price,Categories,Images,Stock,Type
,Blue Widget,WIDGET-001,29.99,Widgets,https://yourstore.com/img/blue-widget.jpg,50,simple
,Red Widget,WIDGET-002,29.99,Widgets > Colors,https://yourstore.com/img/red-widget.jpg,100,simple
,Accessory Item,WIDGET-005,15.00,Accessories,https://yourstore.com/img/item.jpg,25,simple
,Green Widget,WIDGET-003,29.99,Widgets,https://yourstore.com/img/green.jpg,0,simple
,Purple Widget,WIDGET-004,29.99,Gadgets,https://yourstore.com/img/purple.jpg,10,simple

Five separate issues across five rows, and only one of them (the SKU duplicate) produces a visible "Skipping row" message in the import summary. The others silently succeed with bad data.


Fix 1: Price Column Formatting

WooCommerce's price fields expect plain decimal numbers with a period as the decimal separator. Any non-numeric character in the price column — currency symbol, comma as thousands separator, or comma as decimal separator (European locale) — causes the field to import as blank.

This is one of the most common sources of silent failures in product catalog migrations. The row imports successfully, the product appears in your catalog, but the price is blank and the product can't be purchased.

❌ BROKEN — Price column values that import as blank:

"$29.99"    → currency symbol; stores blank
"€29,99"    → currency symbol + European decimal; stores blank
"29,99"     → European decimal comma; stores blank
"1,299.00"  → thousands comma; stores blank
"29.99 USD" → trailing text; stores blank
"free"      → non-numeric text; stores blank

FIXED — plain decimal numbers only:
29.99
29.99
29.99
1299.00
29.99
0.00

For stores migrated from European platforms, the decimal comma issue affects every price in the catalog. Use Data Validator to detect non-numeric values in price columns across your entire product CSV before importing.


Fix 2: Duplicate SKUs

SKUs in WooCommerce must be unique across all products in your store. Importing a CSV row with a SKU that already exists in WooCommerce causes that row to be skipped (unless you've selected "Update existing products" in the import wizard).

Duplicate SKUs within the CSV itself also cause problems — the first row with a given SKU imports, and subsequent rows with the same SKU are skipped.

❌ BROKEN — Duplicate SKU in import file:

SKU column:
WIDGET-001   → Row 1 imports successfully
WIDGET-002   → Row 2 imports successfully
WIDGET-001   → Row 3 skipped: "Skipping row, SKU already exists"
WIDGET-003   → Row 4 imports successfully
WIDGET-002   → Row 5 skipped: "Skipping row, SKU already exists"

FIXED:
WIDGET-001
WIDGET-002
WIDGET-006   ← unique new SKU for what was a duplicate
WIDGET-003
WIDGET-007   ← unique new SKU for what was a duplicate

SKUs can be left blank — WooCommerce will import products without SKUs. But blank SKUs cannot be updated via CSV reimport (no SKU means WooCommerce can't match the row to an existing product on subsequent imports). Assigning SKUs before the first import avoids this problem entirely.


Fix 3: Image URL Format and Accessibility

WooCommerce fetches images from the URLs in your Image column during import. The URL must meet two conditions: it must be a full URL (starting with https://), and the image must be publicly accessible — WooCommerce's server makes an HTTP request to that URL during the import process.

Relative paths (/images/product.jpg), local file paths (C:\store\images\product.jpg), and URLs behind authentication fail silently. The product imports; the image field is blank.

❌ BROKEN — Image URL values that fail during import:

"/images/blue-widget.jpg"           → relative path; can't be fetched
"C:\products\images\widget.jpg"     → local file path; inaccessible from server
"https://yourstore.com/img/404.jpg" → URL exists but returns 404; image blank
"http://yourstore.com/img/item.jpg" → HTTP (not HTTPS); may fail on SSL-enforced stores
"dropbox.com/shared/item.jpg"       → shared link may not serve raw image

FIXED — full, publicly accessible HTTPS URLs:
"https://yourstore.com/wp-content/uploads/2026/03/blue-widget.jpg"
"https://yourstore.com/wp-content/uploads/2026/03/blue-widget.jpg"
"https://cdn.yourstore.com/products/item.jpg"
"https://yourstore.com/wp-content/uploads/2026/03/item.jpg"
"https://dl.dropboxusercontent.com/s/xxxxx/item.jpg"   (direct Dropbox link)

For migrations where product images are on the old platform, the fastest path is uploading all images to your new WooCommerce media library first, then referencing the new wp-content/uploads URLs in the CSV. For large image sets, tools like the WP All Import plugin can handle image migration alongside product import.


Fix 4: Variable Product Structure

Variable products in WooCommerce require a specific CSV row structure: one parent row defining the product, followed by one row per variation. The rows are linked by SKU — variation rows reference the parent product's SKU in the "Parent" column.

This is the most structurally complex part of WooCommerce CSV import, and incorrect structure causes variations to be dropped silently or the entire product to fail.

Variable Product Row Reference (Bookmark This)

PARENT ROW — defines the product, lists all available attribute options:

Name,    SKU,         Type,     Parent, Attr 1 name, Attr 1 value(s),  Price
T-Shirt, TSHIRT-001,  variable, ,       Color,        Blue|Red|Green,   [blank]

Rules for parent row:
✓ Type = "variable" (lowercase)
✓ Attribute value(s) = all options pipe-separated: Blue|Red|Green
✓ Price = blank (price lives on variations, not parent)
✓ Parent column = blank (it has no parent — it IS the parent)
✓ SKU = unique identifier used to link variations below

---

VARIATION ROWS — one row per variant:

Name,    SKU,              Type,       Parent,      Attr 1 name, Attr 1 value,  Price
[blank], TSHIRT-001-BLU,   variation,  TSHIRT-001,  Color,        Blue,          19.99
[blank], TSHIRT-001-RED,   variation,  TSHIRT-001,  Color,        Red,           19.99
[blank], TSHIRT-001-GRN,   variation,  TSHIRT-001,  Color,        Green,         22.99

Rules for variation rows:
✓ Type = "variation" (lowercase)
✓ Parent = parent product SKU (TSHIRT-001)
✓ Attribute value = single value for this specific variation (not pipe-separated)
✓ SKU = unique per variation — critical for future updates via CSV
✓ Name = blank (inherited from parent)
✓ Price = the actual sale price for this variant

The most common mistake: variation rows with blank SKUs. WooCommerce creates the variations on import but can't match them to rows on future re-imports, so updates always create new variations instead of updating existing ones.

❌ BROKEN — variations without SKUs (imports once, breaks on update):

Name,SKU,Type,Parent,Attribute 1 name,Attribute 1 value(s),Regular price
T-Shirt,TSHIRT-001,variable,,,Blue|Red|Green,
,,variation,TSHIRT-001,Color,Blue,19.99
,,variation,TSHIRT-001,Color,Red,19.99

FIXED — every variation has a unique SKU:
T-Shirt,TSHIRT-001,variable,,,Blue|Red|Green,
,TSHIRT-001-BLU,variation,TSHIRT-001,Color,Blue,19.99
,TSHIRT-001-RED,variation,TSHIRT-001,Color,Red,19.99

Fix 5: Category Path Format

WooCommerce uses the > character as the separator for category hierarchy. A product in "Clothing > Shirts > Men's" is nested under three levels. The separator must be > (space, greater-than, space) — not a slash, not a pipe, not a comma.

Non-existent categories are created during import. The category path format determines whether WooCommerce creates nested categories correctly or creates a flat category with the full path string as its name.

❌ BROKEN — Category path format errors:

"Clothing/Shirts"           → slash separator; creates "Clothing/Shirts" as flat category
"Clothing | Shirts"         → pipe separator; creates "Clothing | Shirts" as flat category
"Clothing,Shirts"           → comma; treated as two separate categories at root level
"Clothing > Shirts"         → missing spaces around >; may work but inconsistent

FIXED — space > space as separator:
"Clothing > Shirts"         → creates Shirts nested under Clothing
"Clothing > Shirts > Men's" → creates Men's nested under Shirts nested under Clothing
"Electronics > Cables"      → creates Cables nested under Electronics

If a product belongs to multiple categories, separate them with a comma: "Clothing > Shirts, Sale Items". This assigns the product to two top-level-or-nested categories simultaneously.


Common Scenarios

Catalog Size Strategy: Small vs Large Import

Catalog size    → Recommended approach
────────────────────────────────────────────────────────────
< 500 products  → Manual fixes are practical.
                  Fix errors row by row in your spreadsheet.
                  Single import, check results.

500–5,000       → Validate before importing.
                  Run Data Validator first to catch all format
                  errors before you upload. Fix in bulk.
                  Consider batches of 500 if first import fails.

5,000+          → Batch + stage.
                  Split into batches of 500–1,000 rows.
                  Test on a staging site before production.
                  Use "Update existing products" for re-imports.
                  PHP upload limits may apply — verify with host.

Server limits matter at any size: PHP's upload_max_filesize defaults to 2MB–8MB on shared hosting. A catalog of 1,000 products with image URLs and descriptions can exceed this. Check with your host before attempting large imports, or split the file regardless.

Migrating from Shopify to WooCommerce

Shopify exports use a different column naming convention and a different format for variants. Shopify's "Option1 Name" / "Option1 Value" structure needs to be mapped to WooCommerce's "Attribute 1 name" / "Attribute 1 value(s)" columns. Shopify exports prices without currency symbols (correct for WooCommerce) but uses commas as thousands separators in some locales — remove those before importing.

Importing a product catalog from a supplier spreadsheet

Supplier spreadsheets are not formatted for WooCommerce import. They typically lack the Type column, use inconsistent SKU conventions, include currency symbols in prices, and have image filenames rather than URLs. Budget time for structural reformatting before the import attempt, not after.

Updating existing products without creating duplicates

When reimporting to update existing products (price changes, stock updates), use WooCommerce's "Update existing products" import option and reference products by SKU. Without SKUs, WooCommerce has no way to match incoming rows to existing products — it creates duplicates instead of updating. If your current catalog has no SKUs, add them before attempting any update imports.


Additional Resources

Official WooCommerce Documentation:

Technical Standards:

E-commerce Data Standards:

Tested: WooCommerce built-in CSV product importer, WooCommerce 8.x on WordPress 6.x, March 2026. Each error type reproduced using standard WooCommerce export templates and common migration file formats.

PLATFORM SPECIFICATION SOURCE
Platform: WooCommerce
Source: WooCommerce Documentation — Product CSV Import Suite
URL: https://woocommerce.com/document/product-csv-import-suite/
Verified: March 2026
Next re-verify: June 2026

Values in this post reflect official documentation at the verification date.
WooCommerce updates import behavior with major version releases — the official source is authoritative.

FAQ

The most common cause is currency symbols or non-numeric characters in the price column. WooCommerce expects a plain decimal number — 29.99 not $29.99. Remove all currency symbols and comma thousands separators from the Regular Price and Sale Price columns. For European stores where , is the decimal separator, convert all prices to period-decimal format (29.99 not 29,99) before importing.

Variable products require one parent row (Type = variable) and one row per variation (Type = variation). Each variation row must reference the parent's SKU in the Parent column and specify the exact attribute value (e.g., Color = Blue, Size = M). Attribute values on the parent row use pipe separators to list all available options (Blue|Red|Green). Each variation row should have its own unique SKU for reliable future updates.

Image URLs must be full https:// URLs pointing to publicly accessible images. Relative paths (/images/product.jpg), local file paths, and URLs behind authentication or password protection all fail silently. WooCommerce makes an external HTTP request to fetch each image during import — if the request fails, the image is skipped and the product imports without it.

Check "Update existing products" in the WooCommerce import wizard before uploading. Products are matched to existing records by SKU. Without a SKU match, WooCommerce creates a new product instead of updating the existing one. If your current products don't have SKUs, add them before attempting any update import.

Yes, but through different import mechanisms. WooCommerce's built-in CSV importer handles products only. Customer imports require a plugin (WP All Import, Customer/Order/Coupon Export) or manual user creation. Order imports similarly require a dedicated plugin. The built-in importer is for product catalog management only.

WooCommerce itself doesn't impose a hard row limit, but PHP's upload file size limit on your server determines the maximum file size. The default upload_max_filesize in PHP is often 2MB–8MB, which is insufficient for large catalogs. Increase this value in your server's PHP configuration (php.ini) or contact your hosting provider. For catalogs above 5,000 products, splitting into batches of 500–1,000 rows is advisable regardless of file size limits.


Validate Your WooCommerce Import File Before Uploading

Catch duplicate SKUs, price formatting issues, and missing product names before WooCommerce skips them
Validate image URL format and flag relative paths that will fail silently
Files validate entirely in your browser — your product catalog and pricing never transmitted to any server
Fix only the failing rows; reimport with "Update existing" to avoid duplicating products that already landed

Continue Reading

More guides to help you work smarter with your data

csv-import-guides

CSV Delimiter Errors: Fix Comma vs Semicolon for International Teams

Stop all data in Column A errors. Learn comma, semicolon & tab CSV delimiters plus quick fixes for global teams.

Read More
csv-guides

How to Split Large CSV Files Without Excel (Even 1M+ Rows)

Need to split a massive CSV file but Excel keeps crashing? Learn how to split files with millions of rows safely in your browser without uploads.

Read More
excel-guides

Batch Convert Multiple Excel Files to CSV Without Opening Each One

Opening 50 Excel files one at a time to save as CSV takes 45 minutes and produces inconsistent results. Three methods handle the same task in under 60 seconds — none require opening a single file.

Read More

We use analytics cookies to improve SplitForge. Your files never leave your browser — ever. Privacy policy