31 tools· updated sep 2026

Google Merchant Center feed: seven things a 550,000-item feed had wrong before the first ad

Marek.

  • ad-platforms
  • measurement
  • field-notes

A Google Merchant Center feed is the product file Google reads before it shows a Shopping ad or a free listing: one record per item, with the id, title, description, link, image, availability and price the Product data specification requires. In August 2026 I audited one for a European car-parts store that runs on a hosted e-commerce platform, ahead of its first Shopping campaign. The file had 548,575 items, 13 field names and faults nobody had asked the platform vendor about. Here is what I found, what one email fixed, and what was still broken on 4 September.

  • The file. 548,575 items, 45.8 MB compressed on the wire, 373.8 MB unpacked, four minutes to download, 11.3 seconds to stream-parse.
  • The identifiers. g:mpn present in every item and empty in every item. g:gtin missing in 37,866 items, 6.9 percent, so those items had no unique product identifier (GTIN or MPN).
  • The images. g:image_link missing in 20,942 items, 3.8 percent, and the image host refused requests without a referer, so Google's crawler got nothing.
  • The availability. in stock in 548,575 of 548,575 items, no other value, no quantity field. In a sample of 22 product pages, 9 said unavailable while the feed said in stock.
  • What it means. No bidding structure, built by hand or through the Google Ads API, fixes a feed whose availability is a constant; Google disapproves exactly the mismatch this file produces at scale.

What is Google Merchant Center feed?

A Google Merchant Center feed is the data source that tells Google what you sell: one record per product carrying an id, title, description, link, image, availability and price. Google reads it into Merchant Center, checks it against your landing pages, and serves the approved items in Shopping ads and free listings.

The Product data specification marks seven attributes as required: id, title or structured_title, description or structured_description, link, image_link, availability and price. Others are conditional: brand for new products outside media, mpn only when there is no manufacturer-assigned GTIN, condition for used or refurbished items, availability_date with preorder. availability takes four values: in_stock, out_of_stock, preorder and backorder.

What is a Google feed?

In Merchant Center a Google feed is any product data source Google can parse: an XML file in RSS 2.0 with the g: namespace, a tab-delimited text file with one attribute per column, a Google Sheet, or records sent through the Merchant API. The container differs, the attributes do not.

The Create a product file page takes .txt, .xml or .tsv files up to 4 GB; a spreadsheet needs attribute names in the first row, "each in its own column", one product per row. The RSS 2.0 specification adds the XML rule: every attribute carries the g: prefix, declared as xmlns:g="http://base.google.com/ns/1.0", inside <rss>, <channel> and <item>. The Merchant API is the programmatic route, in Google's words a way to "manage how your business and products appear on Google".

Google Merchant Center XML feed example

The smallest item I would accept from a platform, my own, with exactly the seven required attributes and nothing a store cannot keep true:

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
  <channel>
    <title>Example car-parts store</title>
    <link>https://www.example.com/</link>
    <description>Product data for Merchant Center</description>
    <item>
      <g:id>BRK-10442</g:id>
      <g:title>Front brake pad set, ceramic, with wear sensor</g:title>
      <g:description>Set of four ceramic front brake pads with one wear sensor. Fits the models listed on the product page.</g:description>
      <g:link>https://www.example.com/brake-pads/brk-10442</g:link>
      <g:image_link>https://img.example.com/brk-10442-main.jpg</g:image_link>
      <g:availability>in_stock</g:availability>
      <g:price>49.90 EUR</g:price>
    </item>
  </channel>
</rss>

The spec spells the value in_stock; the audited feed wrote in stock with a space. The spelling was never the problem. Being the only value in the file was.

Google Merchant Center feed template

A template is a header row. For a tab-delimited file this is the line I hand to a vendor, required attributes first, one tab between names:

id	title	description	link	image_link	availability	price	brand	gtin	mpn	condition	product_type

After price, brand, gtin, mpn and condition are conditional and product_type is optional. A vendor who cannot fill mpn should drop the column, not ship it empty: the spec says "Only submit MPNs assigned by a manufacturer" and, in doubt, none at all.

Is Google Merchant Center free?

Yes. Google's Get started page calls Merchant Center "a free tool", and the free listings page says products in a free listing "can appear at no cost on Google Search, Google Maps, Gemini, YouTube, the Shopping tab, Google Images, and Google Lens". What costs money is Shopping ads, billed through Google Ads, plus keeping the feed true.

Free is where the cost hides. This audit took a week of my time in August and one long email; the fixes that landed were engineering hours on the vendor's side.

How to create a Google feed?

Export one record per sellable product with the seven attributes Google requires: id, title, description, link, image_link, availability and price. Add brand and GTIN or MPN for new products. Save it as RSS 2.0 XML or a tab-delimited file, register it as a data source in Merchant Center, set a daily fetch, and read the diagnostics before any campaign.

The long version, for a store whose export is someone else's code:

  1. Define sellable before exporting. The audited platform exported the whole catalogue, 548,575 rows; items with no stock are future disapprovals with prices attached.
  2. Make availability come from stock at generation time, never from a default. No stock concept in the export means stop here.
  3. Ship brand plus gtin or mpn for new products, and identifier_exists set to no only in the three cases the spec lists (table below).
  4. Images per the image_link page: one http or https URL, RFC 3986 compliant; Googlebot and Googlebot-Image allowed in robots.txt; at least 500 x 500 pixels, enforced from 31 January 2027; no placeholders.
  5. product_type as a full path in the documented format, Home > Women > Dresses > Maxi Dresses, up to 5 values; only the first value organizes bidding and reporting.
  6. Register the URL as a data source, set the fetch schedule, then prove the file changes: two downloads a week apart, different Last-Modified, different hashes.

Seven things the feed had wrong

Snapshot from the full-file pass on 4 September 2026. The 19 August copy gave the same counts to the item, because the file had not changed. The whole file uses 13 field names: id, brand, title, link, description, price, availability, condition, product_type, image_link, gtin, sale_price and mpn. Nothing else appears in 373.8 MB.

FieldState in the feedWhat the spec saysEffect
g:availabilityin stock in 548,575 of 548,575 items; no other value; no quantity field under any nameMust match landing page and checkout; out of stock on the page with in_stock in the data gets the product disapproved9 of 22 sampled pages sold nothing while the feed said in stock; a disapproval pool nobody can size
g:mpnTag in 100% of items, value in 0%Required only when there is no GTIN; submit only manufacturer-assigned MPNsThe 37,866 items without a GTIN have no unique product identifier at all
g:gtinMissing in 37,866 items (6.9%)Strongly recommended; the correct GTIN "will ensure the best user experience and result in the best performance"Those items fall back on MPN, which is empty
g:image_linkMissing in 20,942 items (3.8%); image host refused requests without a refererRequired; one URL; Googlebot and Googlebot-Image must be allowed; no placeholders20,942 items cannot serve; the other 527,633 could not be crawled until the vendor dropped the filter
g:product_typeEmpty in 3.2% of items, about 17,600Optional; first value organizes bidding and reporting; up to 5 valuesAbout 17,600 items fall outside any product-type campaign structure
google_product_category, identifier_exists, shippingAbsent from the fileidentifier_exists is no for a media item without a GTIN, an apparel item without a brand, or any other product with no GTIN and no MPN plus brand; a product that has identifiers and says no "may be disapproved"No way to tell Google which of the 37,866 items without GTIN or MPN legitimately lack one
The file itselfLast-Modified stuck at 11 August 21:42; 19 August and 4 September copies identical by SHA-256Automations "aren't a replacement for regular updates of your product data"Every price and availability value aged by the day

On the missing quantity field: a zero result is only evidence if the search could have found a hit. I ran the field-name pattern against test names first: g:quantity, g:stock_quantity and g:sold_out matched, g:brand did not, and the same pattern then found nothing across 548,575 items. There is no stock information in this file under any name. g:sale_price, in 15,391 items, 2.8 percent, is not a fault; it is the one field that looks like a person set it on purpose.

Google shopping feed errors that come from availability

The availability page leaves no room: "The values in your data source should always match the information on your website." Then the sentence that decides this feed: "If we find that a product is out of stock on your landing page or during checkout, but the availability attribute is set to in_stock in your product data, we disapprove the product." Diagnostics reports it as a mismatched value found by page crawl.

Run that rule against a file where every item says in stock. My sample: 22 product pages from the feed, opened by hand; 13 were buyable and matched the feed, 9 showed unavailable. I would not stretch 41 percent across the catalogue from 22 pages, and I do not need to: any share above zero means the crawl keeps finding mismatches, each one a disapproval the feed cannot prevent, because it has no source of truth for stock.

Merchant Center's answer to small mismatches is automations, which read "the structured data markup on your website" and update price, sale_price, availability and condition from the landing page; they "should already be turned on in your Merchant Center account". Two sentences on that page rule them out here: they are "designed to fix temporary problems with your price, availability, and condition accuracy for a small percentage of your products", and "Automations aren't a replacement for regular updates of your product data." A constant availability is not a small percentage with a temporary problem; it is the whole file with a structural one. When the extractors cannot read price, availability or condition, the products "will be subject to item-level disapprovals", and this store's product-page structured data pointed at an image path that returned a PHP message.

What the platform vendor fixed first and what it did not

The audit went to the vendor as one email with a ranked list: first, automatic refresh of the file at least once a day; second, real MPN values; third, images. Everything else was housekeeping.

By 4 September the images had moved. The image host had been filtering requests by referer; after the change I got 200 with no referer, with a google.com referer and with a Googlebot-Image user agent. Nonexistent image paths now return 404 instead of 200 with an HTML page inside. All 527,633 image URLs point at a domain that answers; eight sampled, eight images back. The image_link page gives 24 to 48 hours only for a robots.txt change; a new image URL is recrawled "typically within 3 days (24-72 hours)", and new content at the same URL "can take significantly longer (up to 6 weeks)". The referer fix changed no URLs, so the 6-week case applies.

The sitemap moved too: accepted by Search Console in two seconds, zero errors. It also lists 50,000 of 548,575 URLs, and the sitemap report showed no error for a file covering 9 percent of the catalogue. Coverage you compute yourself, feed count against sitemap count, through the Search Console API or by hand.

What did not move by 4 September: the two items at the top of my list. availability is still in stock in every item. g:mpn is still a tag with nothing inside. Last-Modified still reads 11 August 21:42, and the file's SHA-256 matches the 19 August copy once line endings are normalized. In the same bucket: a zero-byte robots.txt, which allows everything and tells me nobody has opened it, and an old feed.xml of 223 bytes that still answers, empty.

The pool I would advertise from a feed like this

With no stock signal in the file there are two honest options: wait for the vendor to make availability real, an export that reads stock at generation time plus a fetch at least daily, or advertise only what a person confirmed buyable on the day the ads run. The second is what I gave the store for its first campaign.

Mechanically: keep the items with a GTIN, an image and a product_type, which removes the 37,866, the 20,942 and the 17,600 in one filter; open each remaining candidate's page and confirm it can be added to the basket at the listed price; build the first campaign on the survivors only. For a 548,575-row catalogue that is a few hundred items, chosen by margin and search demand. The 22-page sample proved the mismatch exists; sizing it needs the vendor's stock table, the one thing the export never reads.

The verdict

No badge on this one. RUNNING, TESTED and WATCHING are for tools, and the field notes rules say what each means; this is a note from a job. Merchant Center did nothing wrong here: it reads the file, crawls the pages and disapproves exactly what its documentation says it will.

The finding is about hosted platforms. A vendor can ship a feed that is 100 percent present on every required attribute and 0 percent useful on the one that matters, and no validator will catch it, because a constant is a valid value. The check is dumb and cheap: count the distinct values of availability, look for a quantity field, compare Last-Modified across two weeks, open twenty product pages. The file checks take seconds; the pages take a person. For the first campaign, the pool is what that person verified. For the second, it is whatever the vendor's export has learned to read in between.