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:
- Check the Name column — Every row must have a product name. Rows with a blank Name are skipped silently.
- 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.
- Check the Regular Price column — Remove all currency symbols (
$,€,£) and comma thousands separators. Price must be a plain decimal number:29.99, not$29.99or29,99. - Check image URLs — All image values must be full URLs starting with
https://. Relative paths like/images/product.jpgfail. - 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:
| Column | Required | Format | Common mistake |
|---|---|---|---|
| Name | ✅ Yes | Any text string | Blank = row silently skipped |
| SKU | No | Alphanumeric, unique | Duplicate = "Skipping row, SKU already exists" |
| Regular price | No | Plain decimal: 29.99 | Currency symbol = blank price |
| Type | No | simple / 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 / Symptom | Root Cause | Fix |
|---|---|---|
| Row skipped, SKU already exists | SKU matches an existing product | Use "Update existing products" or deduplicate SKUs |
| Price blank after import | Currency symbol or comma in price column | Use plain decimal: 29.99 not $29.99 or 29,99 |
| Images missing after import | Relative URL or inaccessible image URL | Use full https:// URLs; verify URLs are publicly accessible |
| "Invalid product type" | Type value not in accepted set | Use: simple, variable, grouped, or external |
| Variations not created | Variable product structure incorrect | Parent row + variation rows; attributes must be defined |
| Category blank after import | Category path uses wrong separator or doesn't exist | Use > for hierarchy: Clothing > Shirts |
Table of Contents
- Why WooCommerce Import Has Two Failure Modes
- Fix 1: Price Column Formatting
- Fix 2: Duplicate SKUs
- Fix 3: Image URL Format and Accessibility
- Fix 4: Variable Product Structure
- Fix 5: Category Path Format
- Common Scenarios
- Additional Resources
- FAQ
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:
- WooCommerce — Product CSV Import Suite — Official CSV product import guide and column reference
- WooCommerce — Managing Products — Product types, attributes, and variations documentation
Technical Standards:
- RFC 4180: CSV Format Specification — Official CSV structure standard that WooCommerce's importer follows
- Unicode Standard: Character Encoding — Character encoding reference for international product data
E-commerce Data Standards:
- GS1 Global Trade Item Numbers — GTIN/EAN/UPC barcode standard used in WooCommerce product data
- Schema.org Product Type — Structured data standard for product information
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.