The Shopify inventory CSV: every column, every failure mode
The Shopify CSV export for inventory: every column explained, both export formats, and why imports fail validation — all verified October 2026.
InventoryX is in development and not available today. ClearStock is the live Shopify app.
Short answer: the inventory CSV is exported from Products → Inventory → Export and comes in two formats — All states (one row per variant per location, with a write-safe On hand (new) column) and Available (location names as columns, available quantities only, no overwrite protection). The import side validates what you send against what the system currently shows, rejects stale rows, caps files at 15 MB, and — the detail that trips people most — never updates SKUs, because SKU lives in the product CSV, not the inventory CSV.
This is the reference page: the columns, the rules, and the failure behaviors, verified against the Shopify Help Center's inventory CSV documentation in October 2026.
Export: pick your format before you pick your fight
Products → Inventory → Export. You choose the location (or all locations), the format, and the scope (current page, all variants, selected, or search-matched).
All states format — one row per variant per location, and the structure that protects you:
| Column | Editable? | What it is |
|---|---|---|
| Handle | No | The product's unique URL identifier — how rows are matched to products |
| Title | No | Product title (optional, blank OK) |
| Option1/2/3 Value | No | The variant's option values — this is how a specific variant is identified |
| SKU | No | Display only. Does not update the SKU — SKU changes go through the product CSV |
| HS Code | Yes | Harmonized System code for duties estimation |
| COO | Yes | Country of origin, ISO country codes |
| Location | No | Your location name — case-sensitive, must match exactly |
| Bin name | Yes | The shelf/rack/bin reference within the location |
| Incoming | No | Units in transit — read-only |
| Unavailable | No | Damaged / quality control / safety stock — read-only here |
| Committed | No | Units promised to unfulfilled orders — read-only here |
| Available | No | Current sellable quantity — read-only here |
| On hand (current) | No | The snapshot from export time — this powers the safety validation |
| On hand (new) | Yes | The only quantity you edit. Leave blank to change nothing |
Available format — Handle, Title, then one column per location with available quantities beneath. Simpler, and no overwrite protection: whatever you put in a location column becomes the quantity. Fine for a controlled one-location update; risky for anything else.
The columns that actually do something
On import, exactly these fields write back: On hand (new) (or the Available-format location columns), Bin name, HS Code, COO, and the four packed-dimension columns (Variant Packed Length/Width/Height and their unit — cm or in).
Everything else is identification or context. That surprises merchants who edit the SKU column expecting it to stick — it won't; the inventory CSV is quantities and location metadata only. Also note the packed-dimension quirk: those four fields belong to the variant, not the location, so every row for the same variant must repeat identical values — a mismatch means none of that variant's rows import (and the rest of the file is unaffected).
The rules that decide whether your import works
Required columns: Handle, Location, and Option1 Value (plus Option2/3 Value when the product has those options). For a no-options product, Option1 Value is Default Title. Missing any of these and the row can't be matched to a variant.
Location names are case-sensitive and exact. "Warehouse" ≠ "warehouse". The location column must name a location that exists; each variant gets one row per location you want to update, and other location rows should be removed.
Whole numbers only. No decimals like 1.5 — positive, negative, and 0 are fine. Not stocked marks a product never stocked at that location.
Blank On hand (new) = no change. This is the correct way to update bin names or HS codes without touching quantities — leave the quantity column empty.
15 MB file cap. Beyond that, split the file.
Blank rows are ignored, not errors. Handy to know when a spreadsheet pasted in a gap.
The failure modes, in order of how often they bite
1. The safety-validation rejection — the good kind. When the CSV contains both On hand (current) and On hand (new), Shopify compares the current snapshot against live quantities at import time. If anything sold or moved since your export, the affected rows are rejected, and you get an email listing the failed rows. This is the feature that stops you from overwriting yesterday's sales with yesterday's numbers. The failure email is not a bug — it's the system telling you to re-export and redo those rows. Your Tuesday export imported on Thursday will reject every row that sold in between.
2. Disabling the safety net by accident. The documented escape hatch: clear the On hand (current) column entirely and keep only On hand (new) — the import then skips validation. Use it only when you truly want a force-set, because it removes the protection against clobbering recent changes. A force-set during trading hours is how you manufacture phantom inventory (count discipline is how you find it later).
3. Wrong-format expectations. Merchants arrive with a product CSV (which has different columns and updates different things) or a hand-built sheet missing Option values. The inventory CSV and the product CSV are different documents for different jobs — don't mix them.
4. Case/format drift in locations. A location renamed last month, a trailing space from a spreadsheet paste — the row silently targets a location that doesn't exist and fails. Copy location names out of Settings → Locations, never from memory.
5. Editing read-only columns and expecting results. Incoming, Unavailable, Committed, and Available can't be set through the CSV — you set On hand, and the states follow. If you're trying to "fix" a Committed number via CSV, that's an orders question, not an inventory one.
The update loop, end to end
- Products → Inventory → Export, All states format, all locations, all variants.
- Open in a spreadsheet, edit On hand (new) only — never hand-type over
On hand (current), and leave rows you're not changing blank. (If you're pasting from a working sheet — like the spreadsheet template — paste values into On hand (new), and paste values only.) - Save as CSV, Products → Inventory → Import, upload, review the import summary, start.
- Check your email for the validation-failure list. Re-export, fix only the failed rows, re-import those.
- File the export. If you're building a Google Sheets dashboard on top of these snapshots, the export-and-import pair is your refresh ritual — same file, two directions.
When to CSV instead of clicking
The CSV is the right tool when the change is systematic: a warehouse re-slot (bin names), a new location's opening stock, HS codes before an international push, or a full reconciliation after a count. It's the wrong tool when the change is judgment-based and small — five SKUs is faster in the bulk editor or on the Inventory page (the click-path loop lives in the bulk edit guide). And it's the wrong tool when you need the adjustment trail: CSV imports don't carry the movement provenance that manual adjustments do, so anything you want explained later should go through the admin instead.
Common questions
How do I export my inventory from Shopify as a CSV? Products → Inventory → Export. Choose the location or all locations, pick the format — All states (one row per variant per location, with On hand (current) and On hand (new)) or Available (location-name columns) — choose the variant scope, and export. Shopify also publishes a sample inventory CSV you can use as a template (Help Center, accessed October 2026).
Why won't my Shopify inventory CSV import? The most common reason is safety validation: your On hand (current) snapshot doesn't match live quantities anymore, so affected rows are rejected and emailed to you with details. Other causes: missing Handle, Location, or Option1 Value columns; case-mismatched location names; decimals in quantities; a file over 15 MB; or mismatched packed-dimension values across rows of the same variant.
Does the Shopify inventory CSV update SKUs or prices? No. The inventory CSV updates quantities (On hand (new)), bin names, HS codes, country of origin, and packed dimensions only. SKU, price, and other product fields live in the product CSV — a separate export/import with its own format.
What does "On hand (current)" mean in the Shopify inventory CSV? It's the snapshot of your quantity at export time, kept for safety validation: at import, Shopify compares it against the live quantity and rejects rows where stock changed in between — protecting you from overwriting sales made after you exported. Clearing that column skips the protection (Shopify Help Center, as of October 2026).
Can I import inventory for a deactivated location? Yes — you can stock an inactive location through the CSV; the location simply stays inactive. That's the documented pattern for pre-stocking a new store or preparing bins before a location goes live.
Next step: do one round trip today on ten SKUs — export All states, change one On hand (new) value and one bin name, import, and read the summary screen. The format only becomes intuitive once you've seen the validation behave, and doing it once on ten rows beats learning it during a 4,000-row reconciliation.