Catalog Ads Not Delivering: A Feed-Health Checklist
When a catalog campaign won’t spend, the instinct is to blame the creative, the audience, or the bid. Much of the time it’s none of those. Catalog and Advantage+ Shopping ads are only as deliverable as the product feed underneath them, and a feed that looks fine in a spreadsheet can be quietly amputating half your inventory before a single impression is served. If your Meta catalog ads are not delivering, start at the feed, not the ad set.
The reason is structural. A dynamic ad doesn’t have one creative to approve — it has one creative per eligible product. Every item in your catalog is reviewed, validated, and gated independently. The ad set can be “Active” and green while the actual pool of servable products has collapsed to a handful of SKUs, or to zero. Delivery isn’t binary here. It degrades item by item, and the platform seldom shouts about it.
For the surrounding account decisions, compare Meta Ads vs Marketplace Ads: How to Assign Channel Roles and use Why Meta Reports Sales but Your Bank Account Doesn’t: Fixing ROAS with Multi-Touch Attribution as the next diagnostic.
Why feed health gates delivery before anything else
Think of the catalog as the real targeting layer. The campaign defines who and how much; the feed defines what can be shown at all. When optimization is starved, it’s in many cases because the set of eligible products is too thin to find profitable matches, or because the highest-intent products — the ones a retargeting pool actually browsed — are the exact ones disapproved or out of stock.
This is why creative iteration feels useless on a stalled catalog campaign. You can rewrite the primary text twenty times; if the underlying products are ineligible, you’re polishing a frame around an empty wall. Diagnose in this order: catalog ingestion, then item eligibility, then availability, then the pixel-to-feed match. Each layer gates the one below it.
The feed-health checklist
1. Item-level disapprovals — the silent majority
Open Commerce Manager, go to the catalog, and filter items by Issues. This is the single highest-leverage check and the most commonly skipped. You’re looking for two buckets:
- Rejected items — fully ineligible, removed from the servable pool.
- Items with warnings — still eligible but degraded (weak images, truncated titles), frequently delivering poorly rather than not at all.
Sort by the issue type and look at the concentration. If 80% of disapprovals share one cause — a single non-compliant claim in a templated description, an image that trips the text-overlay or low-resolution heuristics — you fix it once at the source and recover hundreds of SKUs in one sync. Common repeat offenders: prohibited or restricted product language, before/after imagery, watermarked or placeholder images, and exaggerated health or outcome claims baked into auto-generated copy.
The trap: people check the ad’s status, see “Active,” and conclude delivery is healthy. The ad being approved tells you nothing about how many products inside it are approved.
2. Missing or malformed required fields
A product needs a minimum set of valid fields to be eligible. Incomplete items either get rejected or quietly deprioritized. Audit the feed for:
- id — stable and unique. A changing ID breaks the link between the pixel event and the product.
- title and description — present, non-truncated, no keyword-stuffed garbage.
- availability — a real, accepted value, not an empty cell.
- condition — populated.
- price — a positive number with a currency field that actually matches your storefront’s configured setting. A blank, zero, or malformed price kills eligibility instantly.
- image_link — resolves to a live, high-resolution image. Dead image URLs are a leading cause of silent drop-off.
- link — lands on a live product page, not a redirect chain or a 404.
Field completeness is a ratio worth tracking over time: eligible items ÷ total items. If that ratio drifts down week over week, your feed is decaying — in many cases because a backend export changed shape and nobody noticed.
3. Stock and availability faults
This is where catalog ads die most frequently and most invisibly. The mechanics:
- Items marked
out of stockare suppressed from delivery. Correct behavior — but if your availability mapping is wrong, you suppress sellable inventory. - A scheduled feed that syncs too infrequently lags reality. A flash of stockouts during a sync gap can mark winners unavailable for hours after they’re restocked.
- Availability-source conflicts: pixel-signaled availability, scheduled-feed availability, and any direct API update can disagree. When they conflict, the platform tends toward the more conservative (suppressed) state.
Check the spread between total items and in-stock eligible items. If your bestsellers — the SKUs your warm audience actually viewed and added to cart — are the ones flickering out of stock, the optimization engine loses its best-supported matches and spend dries up even though the campaign is technically live. Increase sync frequency and reconcile your availability source of truth to one system.
4. Pixel-to-feed ID mismatch
Retargeting catalog ads depend on the content_id in your pixel/Conversions API events matching the id in the feed exactly. A prefix, a suffix, a variant-vs-parent ID, or a casing difference, and the join silently fails: the audience “browsed” products the catalog can’t resolve, so there’s nothing eligible to retarget. The campaign runs, finds no matchable inventory, and underspends.
Validate by pulling a handful of recent ViewContent and AddToCart events and confirming their content IDs exist verbatim in the feed. Also confirm content_type (product vs product group) is consistent on both sides. This one check resolves a surprising share of “broad delivers, retargeting won’t” cases.
5. Catalog and account-level eligibility
Before blaming any single item, rule out the layer above:
- Is the catalog connected to the ad account and the campaign actually pointed at it?
- Is the catalog under any policy restriction or pending review at the catalog level?
- Are commerce or business-asset permissions intact, so the ad account can read the catalog?
A catalog-level block produces the most confusing symptom of all: a perfectly configured campaign that simply won’t leave learning, because every product is gated upstream.
A diagnostic order of operations
When delivery stalls, work top-down so you don’t waste time optimizing below a hard block:
- Catalog connection + catalog-level policy — is the whole catalog readable and clean?
- Eligible-item count — how many products can actually serve right now? If it’s near zero, stop and fix the feed.
- Disapproval concentration — find the one or two root causes behind the bulk of rejections.
- In-stock eligible ratio — are your high-intent SKUs the ones being suppressed?
- Pixel-to-feed ID join — does event data resolve to real catalog items?
- Only then touch budget, bid, or audience.
This is exactly the kind of layered, mechanical check that’s easy to skip under pressure and tedious to do by hand across thousands of SKUs. Bach watches feed health continuously and surfaces the eligible-item ratio, disapproval clusters, and stock-suppression patterns as ranked findings, with execution gated behind your approval — so a quiet catalog collapse becomes a flagged issue instead of a week of unexplained underspend.
The takeaway
Catalog and Advantage+ Shopping delivery is governed by the feed first and the campaign second. Before you rewrite a single ad, answer one question: how many products are eligible and in stock right now? If that number is thin, no creative or bidding change will save you — and if it’s healthy but spend still won’t move, your pixel-to-feed ID join is the next place to look. Treat eligible-item count and the in-stock-eligible ratio as the two dials you watch every week. A healthy feed is the prerequisite for everything else; a broken one makes the rest of the campaign theater.