AIScan fix guide cover: 'Two h1 tags, one page title', WordPress and Google chips, a failing page card turning into a passing one.
AIScan fix guide cover: 'Two h1 tags, one page title', WordPress and Google chips, a failing page card turning into a passing one.
AI Readiness

"Multiple H1 Tags" Warning: What It Breaks for AI Crawlers, and How to Fix the Theme That Adds the Second One

Several h1 elements are not a Google penalty, but a first-h1-wins extractor reads your logo as the page title. The causes, the fix, and a counter script.

13 Nov 2026 7 min read
#h1#headings#structured html#content extraction

This guide covers C3 · Content — for WordPress.

Table of contents

Several <h1> elements will not get your page penalised by Google, and Google's own documentation says so. What they do break is extraction: an agent that takes the first <h1> as the page title reads your logo or site name instead of the headline, and AIScan's C3 check marks the page down because it counts exactly one. The fix is usually one block setting or one template line, and it takes about ten minutes.

QuestionAnswer
Is "multiple H1 tags" a Google ranking problem?No. Google Search Central lists "there's no magical, ideal amount of headings" among its SEO myths
Is it invalid HTML?No. The HTML Living Standard only asks that at least one heading in the outline be level 1
So why fix it?A first-h1-wins extractor takes the wrong title, and AIScan's C3 counts one <h1> as a pass
Which AIScan checkC3, Structured HTML, in the content dimension (weight 4, one point each for a single <h1>, a non-empty <title>, a meta description and one JSON-LD block)
How common47 of 836 scanned hosts serve two or more <h1> on the homepage (12 November 2026)
Usual culpritA site title or logo wrapped in <h1> on every page by the theme
Time to fix10 minutes, plus a re-scan

What the standards actually say, and what tools do anyway

Two claims get mixed up here. The first is that several <h1> elements are an error. They are not. The HTML Living Standard's headings and outlines section asks that if a document has any headings, at least one of them be level 1, and that each heading after the first be no more than one level deeper than the one it follows. Nothing there caps <h1> at one. Google's SEO starter guide is blunter still, filing heading count and heading order under things people worry about for no reason.

The second claim is that it costs you nothing. That one is wrong, for a narrow and practical reason. A pipeline that extracts a page title in one pass takes the first <h1> in document order. When the theme puts the site name in the first <h1>, every page on the site reports the same title, and the headline you wrote lands in the body text with no more weight than a paragraph. Audit tools flag the pattern because of this, not because of a penalty.

AIScan grades it the same way. C3, Structured HTML looks at four signals on the homepage and gives one point each: a single <h1>, a non-empty <title>, a <meta name="description">, and at least one application/ld+json block. Two <h1> elements lose that first point.

How often it happens, from our own scans

Across the 836 hosts in our scan corpus (latest site-scope scan per host, 12 November 2026), the C3 evidence splits like this:

<h1> in the served homepageHostsShare
021325.5%
157668.9%
2 or more475.6%

So the headline problem on the web is the opposite one: a quarter of homepages serve no <h1> at all, usually because the heading is rendered by JavaScript and never reaches the HTML a crawler receives. That case is a separate defect, and the render-blindness corpus study has the numbers. The 47 hosts with two or more are the group this guide is for.

Step 1: find out which <h1> is the extra one

Count them in the HTML your server returns, not in the browser inspector, because a crawler that does not run your bundle sees the former. This script names each one, so you can tell the logo from the headline:

#!/usr/bin/env python3
"""h1count.py - count the <h1> elements in the HTML a crawler receives."""
import re, sys, urllib.error, urllib.request

UA = "Mozilla/5.0 (compatible; h1count/1.0)"

def h1s(url):
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "text/html"})
    html = urllib.request.urlopen(req, timeout=20).read().decode("utf-8", "ignore")
    html = re.sub(r"<(script|style|template)[\s\S]*?</\1>", "", html, flags=re.I)
    found = []
    for m in re.finditer(r"<h1\b[^>]*>([\s\S]*?)</h1>", html, re.I):
        text = re.sub(r"\s+", " ", re.sub(r"<[^>]+>", "", m.group(1))).strip()
        found.append(text[:70] or "(empty)")
    return found

for url in sys.argv[1:]:
    try:
        found = h1s(url)
    except urllib.error.HTTPError as e:
        print(f"{url}\n  HTTP {e.code}, not checked")
        continue
    print(f"{url}\n  h1 count: {len(found)}  -> {'PASS' if len(found) == 1 else 'FAIL'}")
    for i, text in enumerate(found, 1):
        print(f"    {i}. {text}")

Run it on 13 November 2026 against our own sites and wordpress.org:

$ python3 h1count.py https://aiscan.site/ https://wordpress.org/
https://aiscan.site/
  h1 count: 1  -> PASS
    1. Is your site AI agent ready?
https://wordpress.org/
  h1 count: 1  -> PASS
    1. Meet WordPress

A one-liner does the counting without the labels: curl -s https://yoursite.com/ | grep -o '<h1' | wc -l.

Step 2: fix it at the cause

Cause A, the Site Title block on a WordPress block theme. WordPress core ships core/site-title with a level attribute whose default is 1, so a Site Title block inserted by hand renders as <h1>. The default themes do not have the bug: both Twenty Twenty-Four and Twenty Twenty-Five set {"level":0} in their header pattern, which renders a <p>. If your header was built by hand or by a third-party theme, open Appearance > Editor, open the Header template part, select the Site Title block, and set its heading level to Paragraph or H2 with the level control in the block toolbar. Save the template part, not the page. The core blocks reference lists the attribute if you prefer to edit the block markup directly.

Cause B, a classic theme that wraps the site name in <h1> on the front page. Twenty Twenty-One is the readable example: its template-parts/header/site-branding.php emits the site title inside <h1> when is_front_page() is true, and a plain <p> everywhere else. That is why so many sites fail C3 on the homepage and pass on inner pages. Override that one file in a child theme and change the <h1> to a <p>, keeping the existing class so the styling survives.

Cause C, a page builder hero. Hero and heading widgets carry their own HTML tag setting, and a hero that was duplicated from a template often keeps H1 while the post title block below it is also H1. Set the hero's heading tag to H2 and leave the post title as the single H1.

Cause D, a plugin or widget adding a title. Archive titles, breadcrumb headings and some banner plugins add a heading of their own. Deactivate the suspect plugin, re-run the counter, reactivate. The count tells you which one owns the extra element.

When two <h1> elements are fine

If a page genuinely carries two independent purposes, two <h1> elements describe it honestly, and screen readers will read both. Accept the C3 point loss in that case. It is also fine to leave an empty <h1> out entirely on a page whose title sits in a <title> element and an <h2>, although C3 wants one. Do not chase the count by deleting the headline readers need.

Maintenance: a theme or builder update can put the level back. Re-run the counter after a theme update and after any header edit.

Verify the fix

Run npx aiscan-cli yoursite.com and open C3, Structured HTML on the content checks page. It should list a single <h1> along with the title, meta description and JSON-LD points. By hand, python3 h1count.py https://yoursite.com/ should print h1 count: 1 -> PASS and name your headline, not your logo.

On WordPress, the other three C3 signals (title, meta description and schema) live in your SEO plugin. ThinkRank owns all three in one place instead of leaving two plugins to fight over the same tags, and it migrates settings from Rank Math, Yoast, AIOSEO and SEOPress. Yoast and Rank Math control the same fields if you already run one of them.

Related fixes: heading levels that skip a step are a different finding, covered in heading order and skipped levels, and the per-platform steps for the title, meta and schema points are in title, meta and schema by platform.

Your next step

Count the <h1> elements on your homepage, fix the one the theme adds, then scan the site at aiscan.site and check C3. More short fixes are in the guides.

Frequently asked questions

Does Google penalise a page with multiple H1 tags?

No. Google's SEO starter guide lists heading count and heading order among the things that do not matter for Search, saying there is no ideal amount of headings a page should have. The reason to fix the count is extraction and AIScan's C3 check, not a ranking penalty.

Error: my site audit says "multiple H1 tags" but I only wrote one heading. Where is the second?

It is almost always the site name or logo. Count the h1 elements in the HTML your server returns, with curl -s https://yoursite.com/ | grep -o '<h1' | wc -l, or run the h1count.py script in this guide, which prints the text of each one. If the first says your brand name, the theme owns it.

Error: I changed the Site Title block to a paragraph and the second h1 is still there.

You probably edited a page rather than the template part. The header lives in Appearance > Editor > Header as a template part, and saving the page does not save it. Re-open the Header part, change the Site Title block level, save, then re-run the counter against the served HTML rather than the editor preview.

Error: the count is 1 in my browser inspector but the scan still reports two.

The inspector shows the rendered DOM after JavaScript runs; a scan reads the HTML the server sent. A heading removed or replaced by script still exists in the served markup. Compare the two with curl -s URL | grep -c '<h1' against the inspector count.

How many h1 elements does AIScan's C3 check want?

Exactly one in the served homepage HTML. C3 gives one point each for a single h1, a non-empty title element, a meta description and at least one application/ld+json block, at a check weight of 4. Two or more h1 elements lose the first point and the rest are unaffected.

Is zero h1 better than two?

No, it is worse for the same check and for extraction. In our scan corpus of 836 hosts on 12 November 2026, 213 homepages served no h1 at all against 47 with two or more. A missing h1 usually means the heading is rendered by JavaScript and never reaches a crawler that does not run your bundle.

Do default WordPress themes cause this?

Not the current block themes. Twenty Twenty-Four and Twenty Twenty-Five both ship their header pattern with the Site Title block at level 0, which renders a paragraph. Core's site-title block defaults to level 1 though, so a Site Title block added by hand or by a third-party theme renders as an h1.

Can a page ever have two h1 elements on purpose?

Yes. A page with two genuinely independent purposes can carry an h1 for each, and screen readers will announce both. You lose the C3 point and that is an acceptable trade. What is not worth doing is deleting the headline your readers need in order to make a counter happy.

M Asif Rahman

About the author

Entrepreneur, curious about AI

I have been building companies for a long time, and lately most of my curiosity goes to AI. AIScan is a small personal project I built on a flight from Dubai to Narita. I use it to understand how ready the web is for AI agents, and I share what the scans teach me.

Related guides

Browse every guide by check and platform