FeedMender

FeedMender/Full checks list

Reference

Every check, by family

This is the complete list, grouped the same way the scan report groups findings. Each check shows the attribute it reads and the severity we assign it. For the reasoning behind the areas, read what we check; for how a check earns its place, read how we know.

225 distinct checks, read from registry.py at build time. A further 22 families of code are assembled per attribute at runtime; they are listed after the checks.

Prices and currency 23

We add the missing currency code, convert comma decimals to points, and flag sale prices that are not actually lower.

CodeReadsSeverity
loyalty_price_in_price_field price at risk
price_format price blocks
price_missing price blocks
price_unparseable price blocks
price_zero price blocks
sale_price_currency_mismatch sale_price blocks
sale_price_effective_date_format sale_price_effective_date blocks
sale_price_effective_date_parts sale_price_effective_date blocks
sale_price_effective_date_reversed sale_price_effective_date blocks
sale_price_format sale_price blocks
sale_price_not_lower sale_price at risk
sale_window_without_sale_price sale_price_effective_date at risk
subscription_amount_format subscription_cost blocks
subscription_amount_missing subscription_cost blocks
subscription_currency_invalid subscription_cost blocks
subscription_length_invalid subscription_cost blocks
subscription_length_missing subscription_cost blocks
subscription_needs_category google_product_category blocks
subscription_period_invalid subscription_cost blocks
subscription_period_missing subscription_cost blocks
subscription_repeated subscription_cost blocks
subscription_too_many_fields subscription_cost blocks
subscription_week_on_mobile subscription_cost blocks

Product identifiers 19

We validate every GTIN against the GS1 check digit, repair the ones that can be repaired, and catch valid-looking barcodes that Google rejects anyway because of a restricted prefix.

CodeReadsSeverity
brand_missing brand at risk
brand_placeholder brand blocks
brand_too_long brand blocks
gtin_absent gtin at risk
gtin_absent_fallback gtin at risk
gtin_duplicate gtin at risk
gtin_formatting gtin at risk
gtin_invalid gtin blocks
gtin_repairable gtin blocks
gtin_suspect gtin at risk
id_duplicate id blocks
id_invalid_unicode id blocks
id_missing id blocks
id_too_long id blocks
identifier_exists_contradiction identifier_exists blocks
identifier_exists_value identifier_exists blocks
mpn_placeholder mpn at risk
mpn_suspicious mpn underperforming
mpn_too_long mpn blocks

Titles 6

We strip the promotional text that gets products disapproved, and rebuild thin titles from brand, type and the attributes you already supplied, never from anything you did not.

CodeReadsSeverity
title_all_caps title at risk
title_missing title blocks
title_promotional title blocks
title_thin title underperforming
title_too_long title at risk
title_whitespace title underperforming

Descriptions 4

We strip HTML, cut what is over the limit, and flag descriptions too thin for Google to understand what the product actually is.

CodeReadsSeverity
description_html description at risk
description_missing description blocks
description_thin description underperforming
description_too_long description blocks

Images 25

We fetch every image URL and check it actually responds, is large enough for the 500x500 minimum that becomes mandatory on 2027-01-31, and is really the format its extension claims. Lifestyle images and video links are checked for shape, not fetched.

CodeReadsSeverity
additional_image_count additional_image_link at risk
image_below_future_min image_link at risk
image_below_recommended image_link underperforming
image_format image_link blocks
image_format_mismatch image_link blocks
image_invalid image_link blocks
image_missing image_link blocks
image_multiple image_link at risk
image_non_ascii image_link blocks
image_placeholder image_link at risk
image_policy image_link blocks
image_scheme image_link blocks
image_too_large image_link blocks
image_too_many_pixels image_link blocks
image_too_small image_link blocks
image_unreachable image_link blocks
lifestyle_image_link_format lifestyle_image_link blocks
lifestyle_image_link_invalid lifestyle_image_link blocks
lifestyle_image_link_non_ascii lifestyle_image_link blocks
lifestyle_image_link_too_long lifestyle_image_link blocks
video_link_invalid video_link at risk
video_link_non_ascii video_link at risk
video_link_not_a_file video_link at risk
video_link_too_long video_link at risk
video_link_too_many video_link at risk

Stock and availability 9

We map Dutch and French stock wording onto the four values Google accepts, and retire values that no longer exist in the specification.

CodeReadsSeverity
availability_contradicts_quantity availability at risk
availability_date_missing availability_date blocks
availability_date_past availability_date blocks
availability_date_without_preorder availability_date at risk
availability_derived availability blocks
availability_missing availability blocks
availability_value availability blocks
availability_vehicle_ads_only availability at risk
expiration_date_past (varies) blocks

Variants and attributes 22

We fix colour and size values that Google rejects, separate values that were run together, and flag variants that are not grouped, so each size stops competing against its own siblings.

CodeReadsSeverity
color_code color blocks
color_concatenated color blocks
color_contains_digits color blocks
color_not_a_colour color blocks
color_possibly_concatenated color at risk
color_separator color at risk
color_single_letter color blocks
color_too_long color blocks
color_value_too_long color blocks
condition_contradicts_text condition blocks
condition_value condition blocks
is_bundle_value is_bundle blocks
item_group_duplicate_variant item_group_id at risk
item_group_id_missing item_group_id at risk
item_group_mixed_brands item_group_id at risk
item_group_no_variant_attribute item_group_id at risk
item_group_shared_url link at risk
multipack_value multipack blocks
size_holds_multipack size blocks
size_separator size at risk
size_system_value size_system blocks
size_type_value size_type blocks

Categories 3

We map your own category strings onto the Google taxonomy once per catalogue rather than per product, and flag free text sitting in a field that only accepts official values.

CodeReadsSeverity
gpc_invalid google_product_category blocks
product_type_count product_type at risk
product_type_too_long product_type at risk

EU compliance 8

Unit pricing for food, drink and cosmetics, and EPREL energy labels, required since April 2025. This is the part most tools built for the US market skip.

CodeReadsSeverity
certification_format certification at risk
certification_missing certification at risk
energy_class_legacy energy_efficiency_class at risk
unit_pricing_base_format unit_pricing_base_measure blocks
unit_pricing_base_missing unit_pricing_base_measure at risk
unit_pricing_measure_format unit_pricing_measure blocks
unit_pricing_missing unit_pricing_measure at risk
unit_pricing_unit_mismatch unit_pricing_base_measure blocks

Shipping and returns 59

Shipping is mandatory in Belgium and the Netherlands. We check the composite syntax Google expects, the return window and its fees, free shipping thresholds, minimum order values, pickup cost and handling cutoff times.

CodeReadsSeverity
free_shipping_threshold_country_invalid free_shipping_threshold blocks
free_shipping_threshold_country_missing free_shipping_threshold blocks
free_shipping_threshold_currency_mismatch free_shipping_threshold blocks
free_shipping_threshold_format free_shipping_threshold blocks
free_shipping_threshold_missing free_shipping_threshold blocks
free_shipping_threshold_too_many_fields free_shipping_threshold blocks
free_shipping_threshold_too_many_values free_shipping_threshold blocks
handling_cutoff_country_invalid handling_cutoff_time blocks
handling_cutoff_disable_invalid handling_cutoff_time at risk
handling_cutoff_time_missing handling_cutoff_time blocks
handling_cutoff_too_many_fields handling_cutoff_time blocks
minimum_order_value_country_invalid minimum_order_value blocks
minimum_order_value_country_missing minimum_order_value blocks
minimum_order_value_currency_mismatch minimum_order_value blocks
minimum_order_value_format minimum_order_value blocks
minimum_order_value_missing minimum_order_value blocks
minimum_order_value_surface_invalid minimum_order_value blocks
minimum_order_value_too_many_fields minimum_order_value blocks
minimum_order_value_too_many_values minimum_order_value blocks
pickup_cost_currency_unsupported pickup_cost at risk
pickup_cost_flat_rate_missing pickup_cost blocks
pickup_cost_format pickup_cost blocks
pickup_cost_out_of_range pickup_cost blocks
pickup_cost_repeated pickup_cost at risk
pickup_cost_too_many_fields pickup_cost blocks
returns_country_invalid returns blocks
returns_duplicate_policy returns blocks
returns_fee_missing returns blocks
returns_fee_type_missing returns depends on the file
returns_field_count returns at risk
returns_no_returns_with_fees returns blocks
returns_policy_url returns blocks
returns_restocking_fee_format returns blocks
returns_restocking_percentage_format returns at risk
returns_shipping_fee_format returns blocks
returns_too_many_overrides returns blocks
returns_two_restocking_fees returns blocks
returns_window_contradiction returns blocks
returns_window_days_format returns blocks
returns_window_days_missing returns blocks
shipping_combined_limit shipping blocks
shipping_country_invalid shipping blocks
shipping_dimension_format (varies) blocks
shipping_dimension_range (varies) blocks
shipping_dimension_unit (varies) blocks
shipping_dimensions_incomplete shipping_length blocks
shipping_dimensions_units shipping_length blocks
shipping_postal_code_unsupported shipping at risk
shipping_price_format shipping blocks
shipping_price_negative shipping blocks
shipping_price_out_of_range shipping blocks
shipping_time_format shipping blocks
shipping_times_without_price shipping at risk
shipping_too_many_fields shipping blocks
shipping_too_many_values shipping blocks
shipping_weight_format shipping_weight blocks
shipping_weight_range shipping_weight blocks
shipping_weight_unit shipping_weight blocks
ships_from_country_invalid ships_from_country blocks

Links and crawlability 7

We check your landing page URLs are absolute and reachable, and read your robots.txt for all three Google crawlers, including AdsBot-Google, which ignores wildcard rules and is the reason for the disapproval nobody can explain.

CodeReadsSeverity
link_hardcoded_gclid link at risk
link_invalid link blocks
link_missing link blocks
link_scheme link blocks
link_too_long link blocks
link_tracking link underperforming
link_valuetrack link blocks

Other attributes 40

Field lengths, promotion codes with illegal characters, redirect domains, popularity rank, and attributes Google removed from the specification. Individually dull; collectively the difference between a feed that processes cleanly and one that does not.

CodeReadsSeverity
ads_redirect_domain_mismatch ads_redirect blocks
archive_nested_too_deep (varies) stops the scan
attribute_removed (varies) underperforming
composite_schemas_merged (varies) note
delimiter_inconsistent (varies) stops the scan
delimiter_none (varies) stops the scan
delimiter_semicolon (varies) note
encoding_binary (varies) stops the scan
encoding_bom_removed (varies) note
encoding_not_utf8 (varies) note
encoding_replacement_chars (varies) at risk
encoding_undecodable (varies) stops the scan
file_empty (varies) stops the scan
file_wrong_type (varies) stops the scan
gzip_unreadable (varies) stops the scan
header_control_chars (varies) at risk
header_duplicate (varies) at risk
header_empty (varies) at risk
header_missing (varies) stops the scan
json_malformed (varies) stops the scan
json_not_records (varies) stops the scan
json_ragged (varies) at risk
no_rows (varies) stops the scan
popularity_rank_decimals popularity_rank blocks
popularity_rank_format popularity_rank blocks
popularity_rank_range popularity_rank blocks
promotion_id_invalid promotion_id blocks
quote_unclosed (varies) at risk
quoted_newlines (varies) note
related_product_identifier_chars (varies) blocks
row_wrong_width (varies) at risk
rows_dropped (varies) unmapped (sev)
xlsx_unreadable (varies) stops the scan
xml_malformed (varies) stops the scan
xml_namespace_missing (varies) at risk
xml_no_items (varies) stops the scan
xml_unreadable (varies) stops the scan
zip_empty (varies) stops the scan
zip_multiple_files (varies) stops the scan
zip_unreadable (varies) stops the scan

Assembled per attribute 22

These are not separate checks but one check written once and built for whichever attribute carries the fault, so a currency error reads the same on price as on sale_price. The example each family was proven with is shown.

FamilyReadsSeverity
*_currency_invalid (varies) blocks
*_cutoff_format (varies) at risk
*_format (varies) blocks
*_invalid_chars (varies) blocks
*_missing_apparel (varies) at risk
*_multiple_values (varies) blocks
*_session_url (varies) at risk
*_subattribute_missing (varies) blocks
*_subattribute_too_long (varies) blocks
*_subattribute_value (varies) blocks
*_timezone_format (varies) at risk
*_too_far_ahead (varies) blocks
*_too_few_values (varies) at risk
*_too_long (varies) blocks
*_too_many_values (varies) blocks
*_unknown_subattribute (varies) blocks
*_value (varies) blocks
*import_ file depends on the file
*returns_|_missing returns blocks
*returns_|_value returns blocks
*robots_blocks_ link blocks
*shipping_|_reversed shipping blocks

Your own file will trip a different subset of these. The free scan shows exactly which, against the products they belong to.