// FREE TOOL · XML SITEMAP VALIDATOR

xml sitemap validator

Paste your sitemap.xml — or drop the file in — and get every protocol error with its line number and the fix: loc, lastmod, priority, changefreq, hreflang pairing, and the 50,000 URL limit. Free, in your browser, nothing uploaded.

FreeInstantNo signupRuns in your browser

Also inEnglishDeutschEspañolFrançais日本語한국어Português (Brasil)繁體中文

sitemap.xml · validator

Validation runs as you type. You can also drop a sitemap.xml or sitemap.xml.gz straight onto this box — the file is read and unzipped by your browser and never leaves it.

Errors and warnings
    Report
    
              

    How to validate an XML sitemap

    Three steps, all on this page. The checker reads the file you give it — it does not fetch your site, so paste the XML or drop the file rather than typing a URL.

    1. Paste or drop the file. Paste the XML into the box on the left, or drag sitemap.xml (or sitemap.xml.gz — your browser unzips it) onto it. Validation runs immediately, on every keystroke.
    2. Work down the findings. Every finding carries a line number and the fix. Errors are things a crawler will reject or misread; warnings are valid XML that still costs you something, such as a future lastmod or a duplicate URL.
    3. Copy the report, fix, re-check. The right-hand pane holds a plain-text report — file type, how close you sit to the 50,000 URL and 50 MB limits, and every finding — that you can paste into a ticket. Fix, paste the new file, confirm it comes back clean.

    What this sitemap validator checks

    It runs three passes over the file you paste. First XML well-formedness: unclosed and mismatched tags, an unescaped & in a query string, an undeclared namespace prefix — each reported at the line it happens on rather than as one generic parse failure. Then the sitemaps.org protocol: the root is <urlset> or <sitemapindex> in the http://www.sitemaps.org/schemas/sitemap/0.9 namespace, every entry carries exactly one absolute <loc>, <lastmod> is a real W3C Datetime, <priority> sits between 0.0 and 1.0, <changefreq> is one of the seven allowed words, and nothing else wears the sitemap namespace. Then the limits and the cross-references: 50,000 URLs, 50 MB uncompressed, duplicate URLs, mixed hosts, and xhtml:link hreflang annotations checked in both directions.

    An XML sitemap is a file at a fixed URL that lists the pages you want crawled, each as a <loc> element, optionally with <lastmod>, and grouped under a <urlset> root — or a <sitemapindex> that points at several such files. That is the whole protocol, and it is still the 0.9 schema the search engines agreed on. Which is why a sitemap checker is worth running exactly once per generator change: the failures are mechanical, and each one is a one-line fix once something tells you the line.

    RuleLevelWhy
    Well-formed XML: tags closed and nested, & written as &amp;, every prefix declarederrorA crawler parses the file with a strict XML parser. One stray ampersand and the whole file is rejected, not just that URL.
    Root is <urlset> or <sitemapindex> and declares the 0.9 namespaceerrorWithout the namespace the elements are not sitemap elements — the file parses and lists nothing.
    One <loc> per entry, absolute http(s), at most 2,048 characterserrorA sitemap is read out of context; there is no base URL to resolve /blog/ against.
    <lastmod> is a W3C Datetime with a timezone if it carries a timeerror2026-09-01 08:00:00 and 09/01/2026 are both rejected; lastmod is the one hint Google reads, so a broken one is a wasted field.
    <priority> 0.0–1.0, <changefreq> in the allowed listerrorInvalid values make the entry invalid even though Google ignores both fields.
    Only protocol elements in the sitemap namespace; extensions declare theirserror<lastmodified> and <image:loc> without xmlns:image are the two usual typos.
    50,000 entries and 50 MB uncompressed per fileerrorOver either limit the file is rejected whole. Gzip does not help — the limit is measured before compression.
    hreflang alternates: self-reference, return link, valid code, x-defaulterrorA one-way annotation is discarded by Google in full, silently. See below.
    Duplicate <loc>, mixed hosts, future or coarse <lastmod>warningValid XML that still costs you crawl budget or credibility.
    <priority> or <changefreq> present at allwarningGoogle's own documentation says it ignores them. Worth knowing before you spend a release generating them.

    hreflang in a sitemap, checked in both directions

    Putting hreflang in the sitemap instead of in every page's <head> is the option most large sites take, and it is where a sitemap checker earns its keep — because the failure is invisible. Google's rule is symmetric: if page A names B as an alternate, B's own entry must name A, and every version must name itself. Miss one return link and Google does not fall back to a partial cluster; it drops the annotation for that pair. Nothing in Search Console shouts about it.

    So this validator builds the graph. For each <url> carrying xhtml:link elements it checks that the entry lists its own <loc>, that every alternate pointing at a URL in the same file gets a link back, that no language code appears twice, and that each code is a real ISO 639-1 language with an optional script and region — fr_FR written with an underscore, and a bare country code such as gb where a language belongs, being the two that keep showing up. The one it cannot catch is worth knowing: uk is a valid code, it just means Ukrainian rather than the United Kingdom, so nothing in the file looks wrong. Where an alternate points outside the file it says so rather than pretending to know. Where two URLs differ only by a trailing slash it says that too, because that is the mismatch people stare past. Groups without an x-default get a warning, not an error — it is optional, and it is also the version a searcher lands on when you publish nothing in their language.

    If you are writing the annotations rather than debugging them, the hreflang tag generator emits both forms from one URL pattern — the <link> block for the head and the matching xhtml:link sitemap fragment — so the two cannot drift apart. Generate there, paste the result here, and the return links are correct by construction.

    The limits Google actually enforces, and how to split a file

    Two hard numbers: 50,000 URLs and 50 MB uncompressed per sitemap file. The size is measured before gzip, so compressing a 60 MB file does not bring it under — it only shortens the download. The report above the findings shows how close you sit to both, which is the number worth watching in a growing site, because crossing either limit invalidates the file as a whole rather than truncating it.

    Past that, split by section and publish a <sitemapindex>: one file per content type, or per month, whichever makes the <lastmod> values honest. An index carries up to 50,000 <sitemap> entries, each with a <loc> and optionally a <lastmod> — no <priority>, no <changefreq>, and no <url> elements mixed in, all of which this checker flags. The protocol does not let an index list another index, so the tree is exactly two levels: one index, and the sitemaps under it. Paste an index file here and the validator switches to index rules automatically; it cannot follow the child URLs, since it does not fetch anything.

    A last one that is not a limit but behaves like one: keep the file honest about what exists. Every URL in it should return 200 and be indexable — a <loc> that redirects, 404s or carries noindex teaches the crawler to trust the sitemap less. Confirming that takes a fetch per URL, so it is a server-side job rather than something a page in your browser can answer.

    Why this one takes a pasted file instead of a URL

    Every other free sitemap validator asks for a URL and fetches it from a server. This one runs entirely inside the page you are looking at, and a browser is not allowed to read a file from another domain unless that domain opts in — the same-origin policy, enforced as CORS. Almost no site sends Access-Control-Allow-Origin on its sitemap, so a URL field here would fail on nearly every site anyone typed into it. Rather than ship a field that mostly errors, the tool takes the file.

    Which turns out to cover the cases a URL field cannot reach at all:

    • Not published yet — the file your generator just wrote on your laptop, before the deploy.
    • Built in CI — the artifact from the pipeline, checked before it ever reaches a host.
    • Behind a login, a VPN or a staging password — a fetching validator gets the login page and reports it as broken XML.
    • Internal or air-gapped — nothing about the file leaves your machine, so a sitemap you are not allowed to hand to a third-party server is still checkable.

    The trade is real and worth stating plainly: this tool cannot tell you whether https://yourdomain.com/sitemap.xml actually returns 200, whether robots.txt points at it, or whether the URLs inside it are live. It reads bytes you hand it. To check a published file, fetch it yourself — curl -s https://yourdomain.com/sitemap.xml, or curl -s https://yourdomain.com/sitemap.xml.gz | gunzip — and paste the output. Everything past the parse is a server-side job; that is what Agent SEO is for.

    After the file is valid: sitemap ping is gone

    Several sitemap tools still offer to "ping Google" once your file passes. That endpoint — google.com/ping?sitemap= — was deprecated in 2023 and no longer does anything. If a validator is still selling it as a feature, that tells you when the page was last touched.

    What replaces it is duller and works. Put the absolute URL of the sitemap in robots.txt as a Sitemap: line, which every crawler reads on its own schedule and which needs no account. Submit the file once in Search Console and Bing Webmaster Tools, then leave it alone; resubmitting does not speed anything up. Keep <lastmod> accurate, because it is the only field in the file Google says it uses, and an accurate one is what makes a re-crawl worth scheduling. If you run IndexNow, ping it on publish — that one is alive.

    Then measure instead of guessing. clize seo check --domain yourdomain.com reads your sitemap and your Search Console property together and reports the pages that are in the file but have never earned an impression, with their live HTTP and index status — the honest answer to "did submitting it help", which no validator can give you. While you are in the machine-readable layer, two neighbours share this one's rule that a file should be generated from one source rather than hand-edited: the llms.txt validator for the index agents read, and the FAQ schema generator for markup that has to match the visible page word for word.

    // FAQ

    What does an XML sitemap validator check?

    Three things. That the file is well-formed XML — tags closed and nested, ampersands escaped, namespace prefixes declared. That it follows the sitemaps.org protocol — a <urlset> or <sitemapindex> root in the 0.9 namespace, exactly one absolute <loc> per entry, a valid W3C Datetime in <lastmod>, <priority> between 0.0 and 1.0, and <changefreq> from the allowed list. And that it stays inside the limits and is internally consistent — under 50,000 URLs and 50 MB uncompressed, no duplicate URLs, and hreflang alternates that point back at each other.

    Can this validate a sitemap index file?

    Yes. Paste a file whose root is <sitemapindex> and the checker switches to index rules: each entry must be a <sitemap> with one <loc> and at most a <lastmod>, with no <priority>, <changefreq> or <url> elements mixed in. It cannot follow the child sitemaps, because it never fetches anything — validate each child file by pasting it in turn.

    Can it validate a gzipped sitemap.xml.gz?

    Yes. Drop the .gz file onto the box, or pick it with the file button, and your browser decompresses it locally before the check runs. Note that gzip does not change the size limit: the 50 MB ceiling is measured on the uncompressed file, which is what the report shows.

    How many URLs can one XML sitemap contain?

    Up to 50,000 URLs, and the file may not exceed 50 MB uncompressed. Whichever you hit first is the ceiling. Past it, split into several sitemaps and list them in a sitemap index, which may itself hold up to 50,000 entries. An index may not list another index, so the structure stops at two levels.

    Can I put hreflang in a sitemap instead of link tags in the head?

    Yes, and for large sites it is usually the cheaper option: add xhtml:link elements with rel="alternate", an hreflang and an href inside each <url>. The rules are the same as in the head — every version must list itself and every other version, and the links must be reciprocal. This validator checks that graph in both directions, which is the part that silently fails when a return link is missing.

    Does it support image, video and news sitemap extensions?

    It recognizes the Google image, video and news namespaces and counts their elements without treating them as errors, but it does not validate their internal fields. Anything in an undeclared or unknown namespace is reported, because that is almost always a missing xmlns declaration rather than a deliberate extension.

    Why does it not fetch my sitemap from a URL, and is my file uploaded?

    Nothing is uploaded. The validator is a script running in your browser: nothing you paste or drop leaves the page, there is no account and no signup, and once the page has loaded it works offline. That is also why it cannot fetch a URL — the same-origin policy stops a page on one domain from reading a file on another unless that domain sends CORS headers, which almost no site does for its sitemap. Fetch the file yourself with curl and paste the output; in exchange you can also check files that are not published yet, built in CI, or behind a login.

    clize seo check — free for your own domain

    A valid file is the floor. Then find out what got indexed.

    Checking your own site is free: it reads your sitemap and your Search Console property together, lists the pages with their live HTTP and index status, flags the ones that have never earned an impression, and shows traffic by source with AI engines counted separately. One command from inside your agent.

    $ npm i -g @clize/clize && clize install
    $ clize seo check --domain yourdomain.com
    [ Agent SEO by Clize → ]