When a missing GTIN matters
The GTIN — the number under the barcode, whether it reads EAN, UPC or ISBN on the packaging — helps sales channels recognise the product. WooCommerce gives it a native home, the field labelled GTIN, UPC, EAN, or ISBN on the inventory tab, but nothing forces you to fill it in, so catalogs built before the field existed or imported without it stay silently blank.
- An assigned code helps Google identify the product. Omitting an existing GTIN can limit how an offer is shown. If the manufacturer never assigned one, Google does not require you to invent it. Check the other identifiers your product needs, such as brand and manufacturer part number.
- Other channels have their own code requirements. A marketplace may require a barcode for a category or allow an exemption. Check those rules before treating a blank field as a listing blocker.
- A recorded code can support product matching. Feed and structured-data integrations can use it to identify the product. This check inspects catalog data; it does not verify a particular feed, search result or marketplace listing.
- The gap is invisible from the storefront. The product page looks identical with or without the code, so nobody notices until a feed report or a rejected marketplace listing points back at it.
Google's guidance on product identifiers explains the difference between a missing assigned code and a product that has no GTIN, including handmade goods.
How to find missing GTINs manually
The code lives in postmeta under _global_unique_id.
Products created before the native identifier field existed, or imported without the
field, may have no row at all, so the query has to catch both a
missing row and an empty value. With WP-CLI:
wp db query "SELECT p.ID, p.post_title, p.post_status
FROM wp_posts p
LEFT JOIN wp_postmeta m
ON m.post_id = p.ID AND m.meta_key = '_global_unique_id'
WHERE p.post_type = 'product'
AND p.post_status IN ('publish', 'draft', 'pending', 'private')
AND (m.meta_value IS NULL OR m.meta_value = '')
ORDER BY p.post_status, p.ID;"
Adjust the table prefix if yours isn't wp_. Change
post_type to product_variation to run the
same check on variations, which carry their own field.
The list is one moment's answer. The next CSV import, the next product duplicated in wp-admin, or the next batch from a supplier feed puts fresh blanks back on it. And the query hands you IDs, not codes: someone still has to chase each real GTIN through supplier sheets or the packaging itself before there is anything to type in.
How CatalogLift finds it
Every scan walks the whole synced catalog and reads each product's native identifier field as it came from WooCommerce. A product whose field is missing or empty, with no code in a supported identifier plugin, becomes a finding at medium severity. That establishes a catalog gap, not whether the manufacturer assigned a code. Variations are checked separately, so a parent and its variations each answer for their own code.
If no code was assigned, use Dismiss and explain why the finding does not apply. The decision leaves WooCommerce unchanged and is kept in the finding's history. Never make up a GTIN to clear the list.
There is no AI on this path, and that is deliberate: a GTIN is assigned by GS1, and a model asked to produce one will happily invent a code whose checksum passes every validator while identifying nothing. So CatalogLift never drafts a code. You look the real one up — supplier data, the barcode on the box — type it inside CatalogLift and approve it; nothing reaches WooCommerce before that decision, and the next scan verifies the field is filled and the code is valid. Because CatalogLift keeps watching, an import that adds products without codes surfaces as a fresh finding instead of a quiet regression, and the first scan costs nothing and needs no card.