“Import failed” almost never means the plugin is broken. It usually means the WooCommerce CSV Format CSV file wasn’t structured the way WooCommerce expects, there’s a missing header, there’s a price stored as text, or there’s a category separator that doesn’t match what the importer is looking for. The fix isn’t a better plugin. It’s understanding the file structure before you build or source the file in the first place.
This is a reference, not a tutorial. If you need the actual import walkthrough, that’s covered separately. This page is about getting the file itself right so that the walkthrough goes smoothly the first time.

What Makes a WooCommerce CSV Format “Valid” for WooCommerce
Before the field list, three structural rules matter more than any individual column.
The header row must exist, and it must be first. WooCommerce-style importers match columns by header name, not by position. A file with sku, name, regular_price in a different order and a file with the same three headers in a different order both work, because the match is name-based, not column-position-based. But if the header row is missing or the actual data starts on row one, the import has nothing to map against.
Save as UTF-8 encoded CSV, not just “CSV.” Most spreadsheet programs offer a plain “CSV” export and a separate “CSV UTF-8” option. The plain version can mangle accented characters, curly quotes, and special symbols in product names and descriptions. Always choose the UTF-8 variant explicitly.
A comma is the standard delimiter, but check for embedded commas. If a product description contains a comma, it needs to be wrapped in quotation marks; otherwise, the importer reads it as a new column, and every subsequent field in that row shifts over by one. Most spreadsheet software handles this automatically on save, but files built or edited in a plain text editor need this checked manually.
Core Product Fields
These are the columns that appear in nearly every product CSV, whether you’re building the file from scratch or cleaning up an export from another system.
| Column | Required | Format | Example |
|---|---|---|---|
sku |
Recommended | Text, unique per product | TSHIRT-BLU-M |
name |
Yes. | Text | Blue Cotton T-Shirt |
regular_price |
Yes. | Number, no currency symbol | 24.99 |
sale_price |
No | Number, no currency symbol | 19.99 |
stock_quantity |
Recommended | Whole number | 150 |
stock_status |
No | instock, outofstock, or onbackorder |
instock |
description |
No | Text and HTML allowed | <p>100% cotton, machine washable.</p> |
short_description |
No | Text | Soft, breathable everyday tee. |
categories |
No | Text, multi-value | Apparel > T-Shirts |
tags |
No | Text, multi-value | cotton, summer |
images |
No | URL, multi-value | https://yoursite.com/img/tshirt-blue.jpg |
published |
No | 1 (published) or 0 (draft) |
1 |
Two of these deserve a closer look, since they’re where most formatting mistakes actually happen.
Price fields must be pure numbers. A cell containing $24.99 or 24.99 USD will often import as text instead of a usable price, which breaks sorting, filtering, and sometimes checkout entirely. Strip currency symbols and codes before import; the currency itself is a store-level setting, not something that belongs in the price column.
SKUs should be treated as text, not numbers, inside your spreadsheet. If a SKU is purely numeric, like 00123, Excel and Google Sheets will often auto-convert it and silently drop the leading zeros, turning it into 123 a format that column as plain text before entering SKU values, or the file will look correct on screen while actually containing the wrong data.
Multi-Value Fields: Categories, Tags, and Images
Some columns need to hold more than one value in a single cell, and this is where separator conventions matter.
Categories typically use a > to indicate hierarchy (parent > child) and a comma to separate multiple category assignments: Apparel > T-Shirts, Sale Items puts the product in both a nested category and a flat one. Get the separator wrong and the importer either fails to create the hierarchy correctly or, more commonly, creates a new near-duplicate category instead of matching an existing one.
Tags are simpler, just comma-separated values with no hierarchy: cotton, summer, bestseller.
Images use commas to separate multiple image URLs for a single product, with the first URL typically treated as the featured image: https://site.com/img1.jpg, https://site.com/img2.jpg. These need to be publicly accessible URLs at import time; a broken or private link doesn’t throw an error, it just leaves that image slot empty.

Variable Products: The Parent/Child Row Structure
This is the single most common source of malformed WooCommerce imports, and it’s structurally different from a simple product row.
A variable product needs one parent row defining the product itself (name, description, categories), followed by one row per variation (each combination of size, color, etc.), linked back to the parent by a shared identifier, usually the parent SKU or a matching product name.
| Row type | Key columns | Notes |
|---|---|---|
| Parent | name, type (set to variable), categories, attribute:size, attribute:color |
Defines the product and lists which attributes exist |
| Variation | parent_sku, sku, regular_price, stock_quantity, attribute:size (specific value), attribute:color (specific value) |
One row per actual size/color combination sold |
The mistake that breaks most variable-product imports: treating each variation as a fully independent product row without the parent-child link, which either creates dozens of disconnected simple products instead of one product with variations or fails silently, leaving variations unattached to anything.
Formatting Traps Worth Checking Before You Upload
A handful of specific issues account for most of the “the import ran but the data looks wrong” reports, and this overlaps directly with the broader pre-import checklist if you haven’t reviewed that yet.
- Leading zeros dropped from numeric-looking SKUs, covered above; format the column as text first.
- Dates in the wrong format. If your file includes a sale start or end date, confirm whether the importer expects
YYYY-MM-DDa locale-specific format; mismatches here can silently shift dates or fail the field entirely. - Trailing whitespace in category or tag names.
"Apparel "with a trailing space and"Apparel"without one will not match as the same term, producing an unwanted duplicate. - Smart quotes and special characters copied from Word or Google Docs. These often paste as different Unicode characters than they appear and can cause encoding issues in the description fields specifically.
- Boolean fields as text instead of expected values. A
publishedcolumn containing"Yes"“instead of”1may not be recognized, depending on the importer’s exact expected format.

Order and Customer CSVs Use a Different Field Set
Everything above is specific to product data. Orders and customers have entirely different field structures, line items, statuses, and totals for orders; billing details and purchase history for customers, and trying to reuse a product-formatted file for either won’t work. Order export and its filtering options are covered here, and customer data structure, including the registered-user versus guest distinction, is covered here if either of those is what you’re actually building a file for.
A Quick Way to Test Your File Before a Full Import
Before running a large file against your live store, it’s worth confirming the structure is actually correct rather than finding out mid-import. A fast way to do this: build a trimmed version of your real file with just 5 to 10 rows, keeping every column intact, and run that first.
This isn’t the same as the full staging-environment testing covered in the best-practices checklist; it’s a narrower, faster sanity check specifically for the file’s structure. If those 5 to 10 rows import with the correct prices, correct category assignments, and correct variation linking, the structural issues covered in this guide are very likely handled. If something’s still off, a 5-row file is far easier to debug than tracing the problem through a 2,000-row one.
Once the small file behaves as expected, the full file, assuming the rest of it follows the same structure consistently, should behave the same way.