Validate a product feed before you submit it
"Is my feed valid?" is really three questions, and each one is answered by a different tool. One: is the XML well-formed (can a parser even read the file)? Two: are the required fields present and correctly formatted for the platform you are submitting to? Three: will the platform actually let it serve(policy and quality)? You can fully self-check the first two before you ever submit. The third you can only de-risk, because the platform's own review is the final word. Here is how to do all three for free.
The three levels of valid
Treat these as a stack. A failure at level 1 takes down the whole file, so there is no point checking fields until the parser is happy. Once it is, level 2 is a deterministic checklist you can run yourself. Level 3 is the only one you cannot fully settle in advance.
| Level | The question | Free check | A failure looks like |
|---|---|---|---|
| Well-formed XML | Can a parser read the file at all? | xmllint --noout feed.xml, or any XML parser or browser | One unescaped &, a missing close tag, or bad encoding takes down the whole file and every product drops |
| Required fields, right format | Does every item carry the attributes this platform demands, in the accepted shape? | A per-platform checklist, the platform feed-processing report, or Emberfeed per-feed validation | A missing price, availability, or image_link; a price with no ISO currency code; availability in the wrong vocabulary |
| Policy and quality | Will the platform actually let it serve? | The platform own diagnostics (GMC Diagnostics, Meta Commerce Manager Diagnostics) decide this, nobody else | A promotional overlay on the image, a price that disagrees with the landing page, a restricted product, an image below the floor |
The honest spine of the rest of this guide: levels 1 and 2 you can fully self-check before you submit, level 3 you can only de-risk. A tool can get you cleanly through 1 and 2 and surface most of 3 in advance, but it cannot pre-approve you on 3.
Level 1: is the XML even well-formed?
Before a single field matters, a parser has to be able to read the file end to end. The fastest local check is xmllint, which ships with libxml2 and is already present on macOS and Linux:
- Run
xmllint --noout feed.xml. The--nooutflag suppresses the echoed document so you see only errors. If the file is well-formed, xmllint exits silently with return code 0 and prints nothing. Any problem prints to stderr with a non-zero exit code and a line number. - The number-one breakage in a hand-rolled feed is a single unescaped
&in a title or a URL query string like?colour=red&size=l. It must be written&. One stray ampersand makes the entire file ill-formed, so all of your products vanish at once, not just the one row. - No command line? Open the file in any browser, or paste it into an online XML validator. A well-formed document renders as a tidy tree; an ill-formed one throws a parse error at the offending line.
Level 2: are the required fields there, in the right shape?
A well-formed file can still be rejected for missing or malformed fields. This is the layer a checklist, or a validator, can cover completely before you submit, because the rules are deterministic. The catch is that the required set, and some of the formats, differ by platform. The general shape:
- Google Merchant Center requires 7 attributes on every product:
id,title,description,link,image_link,availability,price.conditionis required only for used or refurbished items. Missingbrand,gtin, ormpnis a limited-visibility warning, not a rejection, since late 2023.google_product_categoryis optional (Google auto-classifies). - Meta catalog requires
id,title,description,link,image_link,availability,condition,price, plus one ofbrand/gtin/mpn. Everyidmust be unique; duplicate IDs are a processing error. - TikTok requires 9:
sku_id,title,description,availability,condition,price,link,image_link,brand. - The Czech price-comparison engines (Heureka, Zboží.cz, Glami) emit a different
<SHOP><SHOPITEM>structure with their own required sets. Those have dedicated guides; this article stays on the global Google, Meta, and TikTok shape.
The format half of level 2 is where a file with all the right fields still fails, because the values are written in the wrong shape:
- Price is a number, a space, and a 3-letter ISO 4217 code:
24.90 EUR. Period as the decimal point, no currency symbol, no thousands separator.299 Kč(a symbol, not a code),299(no currency at all), and299.000 CZK(three decimals) all fail. - Availability vocabulary differs by platform. Google wants the underscored form (
in_stock); Meta wants spaces (in stock). Sending Meta's form to Google is a silent format failure even though the field is present. - Condition is a closed vocabulary (
new/refurbished/used) and is only required where the platform demands it. Anything outside that set is rejected.
If you are writing the feed by hand, the companion guide to build a Google Shopping feed manually has the full attribute table and a copy-pasteable skeleton, and the rejection database documents each failure with its exact diagnostic name.
Level 3: will the platform actually let it serve?
Levels 1 and 2 get you a file that parses and carries the right data. Whether that data is allowed to serve is a judgment only the platform makes, after it fetches your feed and (for some checks) crawls your landing pages. You cannot pre-approve yourself here, but both Google and Meta give you free tools to test on a small sample before you point your live catalog at the feed.
Google: Diagnostics, test uploads, and severity tiers
Merchant Center sorts every issue into three severity tiers. The UI labels and the Content API names are worth knowing because they mean different things for whether a product keeps serving:
- Errors (API:
critical) have caused an account suspension or an item disapproval. The product stops serving. Fix these first, always. - Warnings (API:
error) could hurt performance and will likely lead to a suspension later unless resolved. The product still serves, but degraded. - Notifications (API:
suggestion) are recommended optimizations to improve data quality. Not required.
Google's pre-submit tooling is official and free. Upload as a test lets you process a feed source without it going live; Fetch now forces immediate first processing instead of waiting for the schedule; and the rules testing / preview view shows how a draft attribute rule would change your product data before you apply it. After a test fetch, the Diagnostics tab names the exact attribute and the exact product behind each issue, at account, feed, or item level.
One class of Google disapproval cannot be prevented by feed validity alone, and it is worth understanding why. Price-mismatch and availability-mismatch disapprovals fire because Google crawls your landing page and compares its schema.org structured data (price, priceCurrency, availability) against the feed. If the page and the feed disagree, the product is suspended even though the feed itself is perfectly valid. Keeping them in agreement is a storefront job (the right schema.org markup on the product template) plus a fresh feed, not something a feed checker can settle on its own. The common Merchant Center disapprovals guide walks each rejection back to its cause and fix.
Meta: Commerce Manager Diagnostics
On Meta the equivalent path is Commerce Manager, select the catalog, then the Diagnostics tab for catalog health and the active-product count. Feed uploads surface as two distinct outcomes, and the difference tells you how bad the problem is:
- Items failed to upload means some rows had issues but the rest went through. A partial result.
- Feed upload failed means one or more issues blocked the entire upload. Nothing went through.
A Download Issue Report button and a Summary for Upload Session detail exactly which items failed and why. The processing errors Meta catches overlap with level 2 (missing required fields, duplicate IDs, an invalid price format, a broken image link that returns a 404, all-caps text, an invalid category or enum value, a registration-walled URL, an unsupported file format), so a clean level-2 pass on your side removes most of what would otherwise show up here.
The pre-submit checklist
Run these in order on a small sample before you point any live catalog at the feed. The first four you can settle entirely yourself; the last three are how you de-risk level 3.
xmllint --noout feed.xmlreturns nothing (silent exit 0). Encode any stray&as&, and confirm the file is served as UTF-8 with a realContent-Type.- Every
<item>carries all the required fields for your platform (Google 7, Meta 9, TikTok 9). A quick count, for example the number of<g:price>tags versus the number of<item>tags, surfaces gaps fast. - Price is a number plus an ISO 4217 code; availability is in your platform's vocabulary (
in_stockfor Google,in stockfor Meta); condition is present only where the platform requires it. - Image URLs are public and crawlable (no auth, no robots block, no 404) and above the platform floor (Google enforces 500×500 from January 31, 2027), with no promotional overlay for Google. The GMC image requirements spec has the exact rules.
- Upload as a test (or Fetch now) and read Diagnostics on Google, or the Download Issue Report on Meta, against a small sample first.
- Confirm the landing page's structured data (
price,availability) matches the feed, so a mismatch disapproval cannot fire after you go live. - Fix every Error, triage the Warnings, and only then point your live catalog at the feed.
Related
- How to create a Google Shopping feed XML manually (2026)You can write a Google Shopping feed by hand, it is just RSS 2.0 with a g: namespace. Here is the minimal working skeleton, the 7 required attributes (and which extras you actually need), and how to validate it before Google rejects it.
- How to fix the 20 most common Google Merchant Center disapprovalsA field guide to the rejections that account for the bulk of suspended Google Shopping listings. The cause, the manual fix, the bulk shortcut, and the canonical Emberfeed error page for each one.
- Google Shopping feed optimization: 8 levers, rankedA valid feed is not an optimized one. Here are the eight feed levers that decide how many impressions and clicks you win, ranked by impact, with an honest split of which Emberfeed handles and which are yours.
Ship better catalog ads this afternoon.
Free for 3 months on one feed up to 1,000 products. Connect your XML feed, design a template, paste the new URL into Meta / Google / TikTok.