How to bulk import products into Shopify (CSV guide)

Bulk importing products into a Shopify store using a CSV is the typical method for adding 100s or 1000s of products at one time. This method is useful for new store setup, platform migrations, seasonal product catalog additions and wholesale catalog imports /syncs. Working off of a CSV file can be quick, the format and fields can be a bit rigid and the error messages unhelpful, but generally speaking it is the fastest and preferred method of adding products to a Shopify store without manually and individually using the Shopify API.
A common migration scenario: exporting 1,200 products from WooCommerce, importing them to Shopify via CSV, and getting “There was an error with your import” with no line number or field name. The cause? Spaces in image filenames. A simple find-and-replace to remove spaces fixes it instantly. This guide covers how to avoid these problems from the start.
This covers the exact structure of the CSV columns that Shopify expects, how variant rows are handled, how images are referenced by a URL, common import errors and how to fix them, an alternative to the e-commerce importer tool Matrixify, and the hard limits you should be aware of before you begin. If you have already created a properly formatted CSV, skip directly to the common errors section. If you are starting from a blank template, read from top to bottom.
In this post
- Shopify CSV format explained
- Required and optional columns
- How variant rows work
- Image URL handling
- Common import errors and fixes
- Matrixify: when native import is not enough
- Hard limits to know
- Validate before you import
- FAQ
Shopify CSV format explained
Shopify uses a flat (2 dimensional) format for the CSV file with related products grouped together in rows. Each row of products is itself grouped by having the first row contain product-level attributes (title, body HTML, vendor, tags) followed by subsequent rows that only include variant-level attributes (option values, price, SKU, etc) for the product above it with product-level attributes left empty.
This sounds easy enough to read, and it is. But did you know that Shopify reads from top to bottom. So if the Handle field matches the previous row, but the Title field is blank, that row is treated as a variant to the previous product. When the Handle field changes or a Title field has a value, Shopify treats it as a new product.
Shortcode-ID_ The best way to understand the format is to export your existing products as a CSV from Shopify admin (Products > Export) and then open it up in a spreadsheet editor to see how Shopify structures the file. Use that as your template.
Required and optional columns
Product CSV files from Shopify are usually around 30 fields strong. You don’t need most of them.
Required for any import:
- Handle (the URL slug, lowercase, hyphens instead of spaces)
- Title (on the first row of each product only)
- Variant Price (at least one price per variant row)
Important optional columns:
- Body (HTML) for product descriptions. Can include HTML tags.
- Vendor for brand/manufacturer filtering.
- Tags for collection rules, filtering, and internal organization.
- Published (TRUE or FALSE). Set to FALSE if you want products as drafts during import.
- Option1 Name / Option1 Value (up to Option3). For variants: Color, Size, Material.
- Variant SKU for inventory tracking and image matching.
- Variant Inventory Qty for initial stock levels.
- Variant Inventory Policy (deny or continue, controls overselling).
- Image Src for product images (public URL required).
- Image Alt Text for SEO. If you skip this, Shopify uses the filename.
This company provides a product csv generator that you can use to generate a properly formatted csv file with all your product details. This will save you lots of time and avoid any formatting errors before uploading to Shopify.
How variant rows work
Many applications fail at this point. If your product has 3 colors and 2 sizes, then it has 6 products (variants) of a single product. To handle these in the CSV, the first row contains the full product, while the following 5 rows all have the same Handle, but product fields that are not applicable to the specific row are left empty, while variant fields are populated.
Example for a t-shirt in Red/Blue/Green and S/M:
Handle,Title,Body (HTML),Vendor,Option1 Name,Option1 Value,Option2 Name,Option2 Value,Variant SKU,Variant Price
cotton-tshirt,Cotton T-Shirt,<p>Soft cotton tee.</p>,BrandX,Color,Red,Size,S,TSH-RED-S,29.99
cotton-tshirt,,,,Color,Red,Size,M,TSH-RED-M,29.99
cotton-tshirt,,,,Color,Blue,Size,S,TSH-BLU-S,29.99
cotton-tshirt,,,,Color,Blue,Size,M,TSH-BLU-M,29.99
cotton-tshirt,,,,Color,Green,Size,S,TSH-GRN-S,29.99
cotton-tshirt,,,,Color,Green,Size,M,TSH-GRN-M,29.99
Notes on the key rules for handling similar rows and columns throughout the table: The Handle (i.e. whatever is in the first column on every row) must be identical for rows to be considered similar. Option Name fields must have identical (correct) spelling throughout; i.e. you can’t have “Color” on one row and “Colour” on another, even though both are spelled correctly. Option Values are case-sensitive; thus ” Red” and “red” are two different option values.
Shopify enables up to 3 options per product (Option1, Option2, Option3). The standard variant limit was 100 per product, but Shopify has been rolling out a higher limit of 2,048 variants across all plans. Check your store’s eligibility in the Shopify admin. If you’re still on the 100-variant limit, see our guide on the Shopify variant limit for ways to work around it.
Image URL handling
The Image Src column should contain the public URL to the remote image. This image must be downloadable to Shopify. It gets fetched, then downloaded and hosted on the CDN for the product. The remote url is not used for this image. The image does not go through Shopify’s image processing for The Image Src. The image must be publicly accessible – no authentication or login wall for this to work.
To display more than one image per product, add rows with the same Handle and then fill in the fields of the other product data. Fill in the URL for each image in the appropriate row in the Image Src column. The rows should be in the order you want the images to appear in the product gallery.
Common image URL problems that break imports:
- URLs with spaces. Encode spaces as %20 or rename the files first with our bulk image renamer.
- URLs behind a CDN that requires cookies or referrer headers. Test by opening the URL in a private browser window.
- HTTP instead of HTTPS. Some servers redirect, some don’t. Use HTTPS.
- URLs that return a 301 redirect. Shopify may not follow them. Use the final URL.
- Images larger than 20MB. Shopify’s limit per image file is 20MB. Compress first with our image compressor.
– If you are importing from WooCommerce then the images will work with old site URL provided the old site is still up during import. Please take down the old site after shopify import is complete. Read here for step by step WooCommerce to Shopify migration guide.
Common import errors and fixes
Shopify import error messages are frustratingly vague and don’t accurately explain the real reason for most of the errors. In this post, we’ll shine a light on what’s really going on when you get an error message from the import tool.
- “There was an error importing your file.” Usually means a structural problem: wrong delimiter, missing header, or extra columns. Re-export the Shopify template and paste your data into it. Don’t build from scratch.
- Products imported without variants. The variant rows had a mismatched Handle (extra space, different case). Handles are case-sensitive. Copy-paste the handle from row 1 into all variant rows.
- Images missing after import. The Image Src URLs were not publicly accessible, returned a redirect, or timed out. Test each URL in a private browser window.
- Duplicate products instead of updates. You used “Overwrite existing products” but the Handle in your CSV does not match the existing product’s handle. Shopify matches on Handle, not title or SKU.
- HTML showing as plain text in descriptions. The Body (HTML) column had curly quotes or smart quotes from Word/Google Docs. Convert to straight quotes before importing.
- Inventory not updating. You need to specify the Variant Inventory Policy (deny/continue) and the inventory location must match your Shopify location name exactly.
- Tags not appearing. Tags with commas inside them need to be wrapped in quotes. “Summer Collection, 2026” should be in quotes in the CSV cell, or Shopify reads it as two separate tags.
* Run your CSV file through the Shopify CSV validator before import. It will test for structure, encoding and field related problems.
Matrixify: when native import is not enough
Matrixify (formerly Excelify) is a Shopify application for stores that have outgrown the native Shopify CSV importer. It can import Excel files (no need to export to CSV!), supports all types of Shopify resources, imports metafields and has no file size limit. Its background processing and resumable imports mean that you can import anything from a handful of products to millions of rows.
When to use Matrixify instead of native import: when you hit the 15MB file size limit, when you need to import metafields, when you need to do field mapping during migration from another platform, or when you want to set up recurring scheduled imports of supplier feed data. Matrixify has a free plan for small imports and paid plans for larger imports.
Native importer is fine for small stores with less than 5,000 products for one-time import. However, as the product count goes up, time and debugging issues can be saved with subscription-based Matrixify.
Hard limits to know
These are the limits that bite you mid-import when you didn’t plan for them:
- 15MB file size limit per CSV. Shopify’s documented hard cap. A product with 6 variants and 4 images uses 10 rows, and large Body (HTML) fields eat into the size quickly. Many sources also cite a practical cap around 50K rows, though Shopify’s official docs only specify the file size limit.
- Large HTML descriptions eat space fast. Strip unnecessary HTML formatting before import to stay under the 15MB cap.
- 100 variants per product (standard limit, being raised to 2,048 across all plans). If your import CSV has more than your store’s current variant limit per handle, the excess rows get silently dropped. Combined Listings apps like Rubik bypass this by linking separate products instead of using variants.
- 250 images per product. Shopify’s hard cap on product media. Rare to hit, but stores with fabric swatches or paint samples sometimes do.
- 20MB per image file. Compress before uploading. Most product photos should be under 2MB after optimization.
Even if you are hiting the variant limit? No worries, you can switch to linking products together instead with Rubik Combined Listings, a Shopify app that allows you to register separate products as variants without the need of a Shopify Plus subscription. Each color will get its own URL and product page while looking to the customer as one offer.
Validate before you import
Importing a single failed import can waste 10 to 30 minutes. Always validate the file before uploading.
- Run the file through our CSV validator to catch structural errors.
- Open in Google Sheets (not Excel, which sometimes corrupts encoding) and check for curly quotes, extra columns, and mismatched handles.
- Import a test batch of 5 products first. If those 5 look correct, import the rest.
- Set Published to FALSE on first import so products land as drafts. Review, then publish in bulk.
_raised_after 2.D##Images##Your product images may have been imported but incorrectly assigned to wrong variants. Due to shopify’s restrictions, you cannot specify different images per-variant within a single CSV file. You’ll have to use Rubik Variant Images on the product page to filter and specify variant correct images.
FAQ
What is the maximum CSV file size for Shopify import?
15MB max file size is the documented hard limit. Many sources also cite a practical cap of around 50K rows. Split the file or use Matrixify for larger imports.
Can I import product images via CSV?
Yes. Please fill in a public image URL in the Image Src column. We download it and we re-host it on our CDN. You cannot use multiple images per product, so images need to be set up as separate products with the same Handle.
Why did my variants not import correctly?
The Handle column does not match between the product row and the variant rows. Handles are case-sensitive. Check for trailing spaces, different casing, or typos in the Handle for the product row.
How do I update existing products via CSV?
Export products, adjust the CSV fields as needed and then re-import. Overwrite existing products with the same handle. When importing into Shopify, products are matched by their Handle (not title or SKU).
What is Matrixify and when should I use it?
Matrixify is a Shopify app for advanced and/or large import tasks. Use Matrixify when your data file exceeds the native 15MB limit, you need to import data into Shopify metafields, or you want to schedule a recurring import of data from supplier feeds such as eBay or Amazon.
Can I assign images to specific variants via CSV?
You can set a Variant Image but only partially. You can set 1 featured image to showcase per variant within Variant Images connected to your store. However, you cannot add multiple images per single product variant via a CSV import. You can look into apps like Rubik Variant Images that might support this function.
How do I import products from WooCommerce to Shopify?
Export WooCommerce products from the WooCommerce product edit page as a CSV file. Adjust the file to match the correct order of columns for Shopify. Import the product CSV. Keep the site live during import so Shopify can download the links to the images. Learn more about our WooCommerce to Shopify migration guide.
Related reading
- Shopify product CSV import: format, errors, fixes
- WooCommerce to Shopify migration guide
- Shopify variant limit guide 2026
- Variant images FAQ on rubikvariantimages.com
- Combined Listings explained on rubikify.com
Use Shopify’s provided product CSV template in your admin (Products > Import > Download a sample CSV) to paste in your data, validate the file (http://csv.ie/validate/) before importing. Load in a small test set of 5 products before moving on to the full catalog. This will catch about 90% of the issues that could normally take up a lot of time.