Short answer. Merchant Center shows “Invalid RSS/Atom document format” when your XML is not in a format it supports, and its help page tells you to make sure the root element has been declared correctly. The most common cause is not a wrong root but a missing one at the end: a feed generated on the fly stops when the server runs out of time or memory, so the file opens with <rss> and never closes it. Open the feed and look at the last line — a whole file ends with </channel></rss>.
| Shown in Merchant Center as | Invalid RSS/Atom document format |
|---|---|
| Effect | Whole feed blocked |
| Where to find it | Products → Needs attention, then filter by this issue |
| Free check | Not something a feed file shows; see below for what the check can tell you instead |
What Merchant Center means by “Invalid RSS/Atom document format”
Merchant Center could not read your file as RSS or Atom. Google’s help page for the issue is one sentence long: your data source “isn’t in one of our supported formats”, and you should “make sure your root element has been declared correctly”. The related XML parsing error says only that the system hit an error while processing the feed.
The root element is the tag that wraps everything else — <rss> for a Google Shopping feed, <feed> for Atom. It is declared correctly far more often than this error suggests. What is usually wrong is the other end of the file: the root is opened and never closed, because the export stopped before it finished.
That kind of file is intact for every byte it contains. It opens with a valid header, carries real products, and simply stops — which is why it can look perfect in a browser and still be rejected.
Why it happens
- The export ran out of time or memory. A feed built when the URL is fetched, rather than written to a file beforehand, has to produce the whole catalogue inside one request. The server sends
200and the opening tags before it knows how long that will take, so a PHPmax_execution_time, a memory limit or a proxy timeout ends the response mid-file with no way left to report it. A catalogue that has grown is the usual trigger — which is why a feed that worked for a year can start failing with nothing changed. - The file was uploaded while it was still being written. A scheduled export that writes in place, rather than writing to a temporary name and renaming when done, serves whatever exists at the moment of the fetch.
- A page cache stored part of the response. A caching plugin that wraps a streamed feed can keep only the chunk it happened to see, then serve that to every fetch afterwards.
- The root really is wrong. An export that emits a bare list of
<item>elements with no wrapper, or a namespace declared on the wrong tag, produces the same error honestly. - Something is printed before the XML declaration. A stray blank line, a PHP notice or a UTF-8 byte-order mark ahead of
<?xmlmeans the first thing the parser meets is not a document.
How to fix it
In Shopify
Shopify stores do not generate this feed themselves, so the file comes from a feed app. Open the feed URL the app gave you and scroll to the very end: if the last line is a product rather than</channel></rss>, the file is incomplete and it is the app’s export that needs looking at, not your products. Ask the app to regenerate the feed on a schedule rather than on each fetch.In WooCommerce
WooCommerce has no feed of its own, so a plugin is producing it. Most build the feed while the URL is being fetched, which is exactly the shape that gets cut off on a shared host. Check whether the plugin can write the feed to a file on a schedule and serve that file instead; if it only offers on-the-fly generation, raising the PHP time and memory limits for that request is the next best thing, and some hosts forbid both. Our own free plugin raises both where the host allows it.In a CSV or XML feed
Open the file and look at the last line, not the first. A complete Google Shopping feed ends with</channel></rss> and an Atom one with </feed>. If yours ends on a product, regenerate it and compare the byte size of the two attempts — a file that comes out a different length each time is being cut off, not malformed. Where the export is a script you control, write to a temporary file and rename it when it finishes, so a fetch can never catch it half-written.How long until Merchant Center clears it
The issue clears on the next successful fetch of the data source. Merchant Center refetches on the schedule set for it; you can also trigger a fetch from the data source’s page, which is the faster way to confirm a fix.
Because this error is about the document rather than about products, nothing in the Products list changes while it stands — the file was rejected before any item was read.
What FeedRobin does about it
The free feed check reports a file that ends without closing its root element, and tells you how many products it read before the file stopped, so you can see how much of the catalogue was actually served. It reads the document’s own root rather than looking for </rss>, so a truncated Atom or comparator feed is caught the same way.
What the check does not claim is whether a file cut off like this reaches Merchant Center as this error or is quietly read as a shorter catalogue, because Google does not document that. It documents the neighbouring case — when tags inside one product do not match, “any product containing this error will be skipped” while the rest still process. A malformed root is filed as a different error from that one, which suggests it is treated differently, but a suggestion is not a fact. Treat an incomplete file as unusable.
Questions merchants ask
My feed is complete except for the last tag. Will Merchant Center still read the products in it?
Google does not say, and the two possibilities are very different for you. A file cut off part-way through is readable for every byte it contains, so a lenient parser could take the products it got and a strict one could reject the document outright — the first leaves you with a silently shrunken catalogue, the second with this error. Google’s page for it only tells you to check the root element, and the page for XML parsing errors says no more than that the system encountered an error. What Google does document is the neighbouring case: when a pair of tags inside one product does not match, “any product containing this error will be skipped” while the rest still process. That a malformed root is filed as a separate error is the only hint available, and a hint is not an answer. Treat an incomplete file as unusable either way.
The file opens fine in my browser. How can it be invalid?
A browser renders what it has and does not complain about a document that stops early, and a feed cut off part-way through is valid for every byte it contains. Scroll to the very end instead: if the last line is a product rather than </channel></rss>, the file is incomplete however well the beginning reads.
Why would a feed stop part-way through?
A feed generated when the URL is fetched, rather than written to a file beforehand, is produced inside one request. The server sends 200 and the opening tags before it knows how long the catalogue will take, so a PHP time limit, a memory limit or a proxy timeout ends the response in the middle with no way left to report it. A catalogue that has grown is the usual trigger, which is why a feed that worked for a year can start failing without anything being changed.
How do I stop it happening again?
Generate the feed on a schedule into a real file and serve that file, so a fetch never waits on the catalogue. Where the tool only offers on-the-fly generation, raising the PHP time and memory limits for that one request is the next best thing, and some hosts forbid both — in which case a scheduled file is the only reliable route.
Sources
- googleInvalidRssAtom — Google Merchant Center Help
- googleXmlFeedParseError — Google Merchant Center Help
- googleXmlTagMismatch — Google Merchant Center Help