Every RankMath failure on a custom PHP WordPress build — root cause, exact fix, and registry ID for each one
Ten RankMath failures between 26 February and 12 March 2026. None of them showed a visible error on the frontend. Two required building custom mu-plugins to patch around RankMath’s behavior. Three required the UI because WP-CLI doesn’t trigger the necessary side effects. One was a silent schema failure on three pages that looked completely fine in the browser.
Registry IDs, root causes, and exact fixes — in the order they surfaced.
Context — RankMath Issues
RankMath was installed on 26 February. The first issue surfaced the same day. By 12 March I had documented ten of them, built two workaround mu-plugins, and sent a support email with full technical detail on two specific JSON-LD conflicts. On 16 March, Bhanu replied. His answer confirmed one thing and named a fix for a second problem I’d noticed but hadn’t fully traced. That’s now Issue 11.
The support email, the build of audit.py, and the 71/71 audit system that came out of all this is covered in Post 8 — From 0 to 71/71. This post is just the list.
I found all ten of these failures within the first nine days of the site being live — I documented each one before applying the fix are ordered by when they surfaced. The failure registry IDs are included for cross-reference.
Going deeper? The GEO Pocket Guide covers the full 30-check protocol, section-level audit checklist, and citation rate tracking template — free to download.
The 10 Issues — WordPress Schema
Entity Schema Outputting Wrong Primary Name
Registry: GEO_AUDIT_HISTORY_R1-R8.md (Round 6, Mar 4)
Entity scores dropped during GEO audit Round 6. title_match: False, h1_match: False, conflicting_entities flagged. Entity score: 45 → failing state.
RankMath outputs a combined Person,Organization schema type with the WordPress author (“Artur Ferreira”) as the primary entity name. On a brand site, the Organization (“The GEO Lab”) should appear first. RankMath has no setting to control entity ordering or designate a primary entity site-wide.
Built geolab-entity-fix.php — a mu-plugin that intercepts RankMath’s JSON-LD output via output buffering, parses the schema graph array, and reorders it so Organization appears before Person. Entity score: 45 → 80 (+35).
rank_math/json_ld is the right filter. His view: ordering in the JSON-LD graph doesn’t matter — search engines parse the whole graph, not just the first entity. That may be true for traditional search. I’m not convinced it’s true for AI-driven retrieval, where entity prominence in structured data is less well-understood. The mu-plugin stays. See the Vendor Update below for Bhanu’s exact pattern.Meta Fields Not Saving
Registry: WP_RANKMATH_003
RankMath SEO fields (title, description, focus keyword) blank in the editor panel after saving. Fields appear empty on reload.
RankMath’s REST API integration is disabled by default. Without it, the Gutenberg editor can’t read or write RankMath meta fields via the REST API — which is how the block editor saves post data.
RankMath → Settings → General → REST API → Enable. One toggle.
Focus Keyword Not Saving via REST API
Registry: RANKMATH_FOCUS_002
rank_math_focus_keyword field empty after programmatic post updates via the REST API. Saves correctly in the editor, not via wp-json/wp/v2/posts/{id}.
Even with REST API enabled (Issue 2 fix applied), RankMath doesn’t register rank_math_focus_keyword as a REST-accessible field by default. The field exists in the database but isn’t exposed to the REST API endpoint.
Built rankmath-rest-api.php — a mu-plugin that uses register_rest_field() to expose rank_math_focus_keyword and other RankMath meta fields to the REST API. Required for any programmatic deployment workflow.
Dashboard Showing N/A Scores
Registry: RANKMATH_NA_001
The Score column in the RankMath dashboard shows “N/A” for all posts instead of a numeric score.
RankMath only calculates rank_math_seo_score when a post is manually opened and saved in the WordPress editor. For posts deployed via WP-CLI, the score field is never populated and stays N/A permanently.
Set the field manually after deployment:
wp post meta update $POST_ID rank_math_seo_score 70
Sitemap Index Not Listing Sub-Sitemaps
Registry: SITEMAP_INDEX_001
sitemap_index.xml only listed page-sitemap.xml. All other sitemaps existed and returned valid XML at their direct URLs — but weren’t in the index.
RankMath internal caching. When new content types are added after initial sitemap configuration, the sitemap index cache isn’t automatically invalidated. The index reflects the state at last cache generation.
Toggle the Posts sitemap off, save, then back on in RankMath → Sitemap settings. Forces cache regeneration.
Nuclear cache clear via MySQL — immediate regeneration on next sitemap request:
DELETE FROM wp_options WHERE option_name LIKE '%rank_math_sitemap%'
Post Sitemap Empty
Registry: SITEMAP_EMPTY_002
post-sitemap.xml returned valid XML with an empty <urlset> — no URLs inside despite posts existing.
Posts set to noindex globally, or the sitemap for the post type disabled in RankMath settings. Either condition produces a valid but empty sitemap file with no error message.
RankMath → Titles & Meta → Posts → verify “No Index” is not checked globally. RankMath → Sitemap → verify Posts is toggled on. Check individual posts for per-post noindex overrides.
Noindexed Pages Still Appearing in Sitemap
Registry: RANKMATH_NOINDEX_SITEMAP_001
Pages explicitly set to noindex via RankMath’s per-page settings still appeared in sitemap.xml.
RankMath does not automatically exclude noindexed pages from the sitemap by default. The noindex meta tag applies correctly to the page <head> — sitemap exclusion is a separate setting.
RankMath → Sitemap → General → enable “Exclude Noindexed Pages”. Not enabled by default.
Category Sitemap Won’t Disable via WP-CLI
Registry: RANKMATH_CATEGORY_SITEMAP_001
Attempted to disable category-sitemap.xml via WP-CLI. Command ran successfully, option updated in the database — but the category sitemap continued to generate.
wp option patch update rank-math-options-sitemap tax_category_sitemap false
WP-CLI option patches update the database value but don’t trigger RankMath’s cache invalidation or sitemap regeneration. The sitemap system reads from cache, not directly from the options table.
Use the RankMath UI. RankMath → Sitemap → uncheck Categories → Save Changes. The UI save triggers cache invalidation that WP-CLI doesn’t.
Schema Not Injecting on Custom PHP Templates
Registry: WP_WPHEAD_MISSING_001
Three pages — geo-brand-citation-index, explainer, methodology — had no structured data, no OG tags, no robots meta, and no RankMath SEO fields in the page source. Pages looked completely normal in the browser.
The custom PHP templates were missing <?php wp_head(); ?> before </head>. WordPress and all plugins hook their <head> output to the wp_head action. Without that call, none of it fires. Visual layout is unaffected — it comes from the template body, not the head.
Add <?php wp_head(); ?> immediately before </head> in each affected template. All schema, OG tags, and meta appeared on next page load.
audit.py. Nothing in the current audit system scans custom PHP templates for missing wp_head() calls. It’s in the failure registry as a documented fix, not a prevented regression.FAQPage Duplicate Declaration
Registry: SCHEMA_FAQPAGE_DUPLICATE_001
GSC email: “Duplicate field: FAQPage detected across your site.” Rich Results Test showed two separate FAQPage declarations on the same pages.
JSON-LD FAQPage schema injected via functions.php + HTML microdata itemtype="https://schema.org/FAQPage" on the same pages. Two valid declarations of the same schema type. RankMath had no awareness of the conflict — it only knows about its own JSON-LD output, not microdata attributes in the HTML.
Remove all itemscope / itemprop / itemtype attributes from FAQ HTML sections. Keep JSON-LD only. Re-submit affected pages to GSC.
Going deeper? GEO for WordPress covers the full technical setup — from schema markup to server configuration — for making WordPress sites AI-retrievable.
Vendor Update — 16 March 2026
I sent Rank Math a detailed email on two schema conflicts — the entity ordering problem from Issue 1, and the author URL I’d noticed but hadn’t fully traced. Bhanu replied on 16 March. Below is what he said, and what I’m doing with it.
On entity ordering (Issue 1): Bhanu’s answer: ordering in the JSON-LD graph doesn’t matter. Search engines parse the entire graph, not just the first entity. He confirmed rank_math/json_ld as the filter to use:
add_filter( 'rank_math/json_ld', function( $data, $jsonld ) {
// reorder or modify $data here
return $data;
}, 99, 2);
I disagree with the framing, not the filter. Traditional search engines may parse the whole graph. AI-driven retrieval systems are less predictable on this. I kept the mu-plugin.
Author URL Generating Legacy WordPress Username in Schema
Registry: RANKMATH_AUTHOR_URL_001 · Documented: 16 March 2026 (vendor response)
Rank Math outputs "@id": "https://thegeolab.net/about/jorge/" in the Person schema on every page. The URL does not resolve — the correct author page is /about/. The legacy WordPress username (“jorge”) is used in the generated URL, not the display name or a custom slug.
Rank Math generates author schema using WordPress’s default author data. The WordPress username drives the author URL in the @id field. Display name and custom slug settings do not override the schema output. Changing the WordPress username would break other site systems.
Official filter from Rank Math support — override the author @id in the article entity without touching the WordPress username:
add_filter( 'rank_math/snippet/rich_snippet_article_entity', function( $entity ) {
if ( isset( $entity['author'] ) ) {
$entity['author']['@id'] = 'https://thegeolab.net/about/';
}
return $entity;
} );
rankmath-author-fix.php. The broken @id was live the whole time I was running the audit. I’d noticed /about/jorge/ wasn’t resolving but hadn’t traced it to the username mapping. Bhanu’s reply was what got me there.The Pattern
Ten issues, one pattern: RankMath’s defaults assume a standard WordPress setup. Custom PHP templates, programmatic deployments, WP-CLI workflows, and custom schema implementations all land outside that assumption — and the failures that follow are silent. No frontend errors. No admin warnings. No indication anything is wrong until you check the page source, the sitemap index, the REST API response, or the structured data validator.
Two of the ten required building mu-plugins to patch around RankMath’s behavior rather than configuring it. Three required the UI because WP-CLI updates don’t trigger the side effects RankMath’s systems depend on. Two were marked critical for silent visibility loss. And one — Issue 9 — has no automated prevention. It requires manual inspection of every custom PHP template.
The audit system built in response to these failures — 6 modules, 71 checks, 1 min 38 sec — catches six of the ten automatically. The other four are in the failure registry as documented fixes, not prevented regressions.
Quick Reference
| # | Registry ID | What broke | Fix type |
|---|---|---|---|
| 1 | GEO_AUDIT_R6 | Entity schema wrong primary name | mu-plugin |
| 2 | WP_RANKMATH_003 | Meta fields not saving | Settings toggle |
| 3 | RANKMATH_FOCUS_002 | Focus keyword not saving via REST | mu-plugin |
| 4 | RANKMATH_NA_001 | Dashboard N/A scores | WP-CLI manual patch |
| 5 | SITEMAP_INDEX_001 | Sitemap index incomplete | UI toggle / DB cache clear |
| 6 | SITEMAP_EMPTY_002 | Post sitemap empty | Settings check |
| 7 | RANKMATH_NOINDEX_SITEMAP_001 | Noindex pages in sitemap | Settings toggle |
| 8 | RANKMATH_CATEGORY_SITEMAP_001 | Category sitemap won’t disable via CLI | UI only |
| 9 | WP_WPHEAD_MISSING_001 | Schema not injecting on custom templates | Manual template fix |
| 10 | SCHEMA_FAQPAGE_DUPLICATE_001 | FAQPage duplicate declaration | Remove microdata |
| 11 | RANKMATH_AUTHOR_URL_001 | Author URL using legacy WP username in schema | mu-plugin filter (vendor-confirmed) |
Six of the ten RankMath failures have automated audit coverage. Four do not — the category sitemap UI-only fix, the N/A score manual override, the noindex sitemap toggle, and the REST API field. The undetected failures are the ones that recur. Building detection for them is the next audit.py priority.
Frequently Asked Questions
Why did RankMath schema not inject on custom PHP templates?
Custom PHP templates were missing <?php wp_head(); ?> before the closing </head> tag. WordPress and all plugins hook their head output to the wp_head action. Without that call, no schema, no OG tags, no robots meta, and no RankMath SEO fields fire — while the page looks completely normal in the browser.
Why won’t RankMath sitemap settings apply via WP-CLI?
WP-CLI option patches update the database value but don’t trigger RankMath’s cache invalidation or sitemap regeneration side effects. Those side effects only fire through the admin UI save action. For any RankMath setting that affects cached outputs — sitemaps, schema — use the UI, not WP-CLI.
How do I fix RankMath showing N/A scores in the dashboard?
RankMath only calculates rank_math_seo_score when a post is manually opened and saved in the WordPress editor. For posts deployed via WP-CLI, the score is never populated. Fix: wp post meta update $POST_ID rank_math_seo_score 70 — set the field manually. RankMath overwrites it with a real score the next time the post is opened in the editor.
How do I fix the RankMath sitemap index not listing all sitemaps?
RankMath’s sitemap index cache isn’t automatically invalidated when new content types are added. Toggle the Posts sitemap off and back on in RankMath Sitemap settings to force regeneration. Or clear the cache directly: DELETE FROM wp_options WHERE option_name LIKE '%rank_math_sitemap%'.
How do I expose RankMath meta fields to the WordPress REST API?
Two steps. First, enable REST API under RankMath → Settings → General → REST API. Second, for fields like rank_math_focus_keyword that still don’t appear in REST responses, register them manually with register_rest_field() in a mu-plugin. RankMath doesn’t register all its meta fields for REST access by default.
How do I fix RankMath outputting a legacy WordPress username in author schema?
Rank Math uses WordPress’s default author username to construct the @id URL in Person schema, which can produce a non-resolving URL if your username doesn’t match your author page slug. Use the rank_math/snippet/rich_snippet_article_entity filter to override the author @id in a mu-plugin — no username change required. Confirmed fix from Rank Math support.
What Practitioners Are Saying
“The SITEMAP_INDEX_001 failure is particularly well-documented here — the gap between what the UI shows and what gets served is exactly the kind of thing that wastes hours if you don’t know to check the rendered sitemap directly. The DB cache clear command is the useful detail.”
— Daniel Cardoso, Head of Content Strategy, SaaSMetrics.io
“WP_WPHEAD_MISSING_001 is the most dangerous entry in this list — schema that passes validation but never injects on custom templates is a silent failure. The note that there’s no automated prevention for it is exactly right and refreshingly honest.”
— Marco Silva, Technical SEO Lead, VisibilityStack

