99tools

Sitemap Builder & Validator

runs in your browser

Check a sitemap.xml against the sitemaps.org protocol, or build one from a list of URLs. Finds relative URLs, bad lastmod dates, mixed hosts and duplicates.

Mode

Checked against the sitemaps.org 0.9 protocol — the element set, the 50,000-URL and 50MB ceilings, the seven changefreq values and the W3C date formats. Read in your browser; nothing is fetched or uploaded.

Drop a file here, or .

Drop a sitemap.xml or a sitemap index

Sitemap XML

about this tool

Paste a sitemap and find out what is wrong with it, or paste a list of URLs and get one written. Both happen in the page — nothing is fetched and nothing is uploaded, so a file that has not been published yet is exactly as checkable as one that has.

Two of the four elements do nothing

A sitemap entry can carry four things, and people spend most of their time on the two that are inert.

| Element | Required | What it actually does | |---|---|---| | <loc> | Yes | The URL. Absolute, http or https, percent-encoded, under 2048 characters. | | <lastmod> | No | Read by Google, but only while it stays honest. | | <changefreq> | No | Ignored by Google. A hint at most elsewhere. | | <priority> | No | Ignored by Google. A hint at most elsewhere. |

Google's sitemap documentation says in as many words that it ignores <priority> and <changefreq> values. It works out how often a page really changes by watching it, and it ranks your pages against everyone else's rather than against each other. The protocol itself never claimed more for changefreq than a hint rather than a command, and it sets the default priority of any page at 0.5 — so omitting <priority> already says what most people take the trouble to write in. Both are flagged here as notes, not errors: the file is valid, it is just not doing what was intended.

lastmod is the one that is read, and it fails two different ways. The first is format — it must be a W3C Datetime, so 2026-03-01 or 2026-03-01T10:00:00+00:00. A space instead of the T, which is what almost every database export produces, is not valid, and a crawler drops the element rather than guessing. The second is trust. Google uses lastmod only where it is "consistently and verifiably" accurate, and has said that if you keep reporting yesterday for a page that last changed years ago it will eventually stop believing you. What is checked here is the crude version of that: whether every entry in the file carries the same date, which is what a sitemap rebuilt from scratch every night looks like.

Where the protocol disagrees with itself

sitemaps.org publishes prose and an XSD, and on two points they do not match. This follows the prose, and it is worth knowing where that leaves you.

<lastmod> is the bigger one. The prose points at W3C Datetime, which allows 2026 and 2026-03 on their own, makes seconds optional and makes the timezone mandatory once a time is present. The XSD allows neither short form, requires seconds, and makes the timezone optional. Google sides with the prose — "if you do specify a time, you must also specify a time zone" — so that is what is enforced. A bare 2026 passes here and fails a strict XSD validator.

<loc> length is the smaller one: the prose says "less than 2,048 characters", the XSD says at most 2,048. They disagree about exactly one character, and this takes the prose.

The ceilings, and the thing about gzip

50,000 URLs per file, and 50MB uncompressed. The size limit is measured before compression, so gzipping a 60MB sitemap does not bring it under — you have to split it. The parts go in a sitemap index, which is the same file with <sitemapindex> and <sitemap> in place of <urlset> and <url>, and which carries both ceilings for the sitemaps it names.

An index takes only <loc> and <lastmod>. A <priority> inside one is not a weak signal — it is not part of that schema at all, and it is flagged.

What breaks a real file

A <loc> that is not a fetchable URL. A bare path like /about is dropped silently, which is how a sitemap comes back reported as submitted with nothing indexed. So is a javascript: or mailto: URL, which parses perfectly well and is not a page. Raw spaces are the third: the protocol wants URLs percent-encoded before they are escaped, so a space has to be %20.

An unescaped &. A URL with two query parameters needs &amp;, because a bare ampersand starts an entity reference and makes the whole document unparseable. That is an XML error rather than a sitemap error, so it is reported as one, with its line — and with a warning that only the first is shown, because a strict parser stops at it.

More than one host, or more than one scheme. A sitemap may only list URLs at or below its own location. That directory rule cannot be checked from here, because this never knows where the file will be served from; what is checked is the part that does not need to know — that every URL is on one host and one scheme. Half a file pointing at http when the canonicals say https is not merely redirecting, it is on a different host as far as the protocol cares.

Something the file says that is not true. A <url> holding two <loc> elements, a <loc> with markup inside it, an encoding declaration that is not UTF-8, an index full of <url> elements instead of <sitemap>. These share a shape: the file parses, so most tools say nothing, and the crawler then reads something other than what was meant.

Elements it does not know

An image, video or hreflang sitemap carries elements from other namespaces. The file validates here and those elements are listed by name, so you can see what is present — their contents and their own rules are not checked. The namespace may be bound to a prefix, to the default, or to both at once, and all of those are read.

Building one

One URL per line. Anything that is not an absolute http or https URL is left out and named, duplicates are written once, fragments are stripped, and the five characters the protocol tables are escaped. URLs are written in canonical form — lower-case host, default port dropped, anything outside ASCII percent-encoded — and you are told how many were rewritten, because a sitemap that disagrees with your canonical tags is the problem this is meant to avoid.

One lastmod applies to every URL, which is exactly the pattern described above as the one a crawler learns to distrust. Set it only if it is true of all of them, and an invalid one is left out of the file rather than written into it.

Whether a crawler ever reaches these URLs is a separate question, and robots.txt answers it first — the robots.txt tester shows which of them are blocked before a sitemap gets a say. Beyond that, the meta tag generator writes the canonical tags your <loc> values have to agree with, the URL parser picks a single entry apart, and the XML formatter tidies the file itself.

questions

Do priority and changefreq do anything?
Not for Google, whose sitemap documentation says in as many words that it ignores <priority> and <changefreq> values. The protocol itself only ever claimed changefreq was a hint and not a command, and it sets the default priority of any page at 0.5 — so omitting the element says exactly what most people write into it. They are valid and nothing breaks if you use them, but the hours people spend deciding whether a page is 0.6 or 0.8 buy nothing — this tool flags them as notes so you know they are inert rather than wrong. lastmod is the one element that is genuinely read.
Why is my lastmod being ignored?
Usually because it is not a W3C Datetime. 2026-03-01 and 2026-03-01T10:00:00+00:00 are valid; 2026-03-01 10:00:00 with a space instead of the T is not, and that is what most database exports produce. A crawler drops the whole element when it cannot parse it. The other reason is trust: Google uses lastmod only when it is, in its own words, consistently and verifiably accurate — and has said that if you keep reporting yesterday for a page that last changed years ago, it will eventually stop believing you.
How many URLs fit in one sitemap?
50,000, and the file has to stay under 50MB uncompressed — the size limit is measured before gzip, so compressing a 60MB file does not help. Past either limit you split the URLs across several sitemaps and list those in a sitemap index, which has the same two ceilings applied to the sitemaps it names.
Can a sitemap list URLs on another domain?
Not normally. A sitemap may only contain URLs at or below its own location, so one at /shop/sitemap.xml cannot list /blog/. Cross-domain listing works only when the other host is verified in the same Search Console property, or when the sitemap is named in that host’s robots.txt. Mixed hosts in one file are flagged here because the entries are usually just ignored.
Does a relative URL work in a sitemap?
No. Every <loc> has to be absolute, starting with the scheme and the host, and it has to be under 2048 characters. A path on its own is dropped silently, which is why a sitemap full of them reports as submitted and indexes nothing.
Why does my sitemap fail with an XML error?
Almost always an unescaped ampersand. A URL with query parameters has to be written https://example.com/?a=1&amp;b=2 in the file, because a bare & starts an entity reference. The five the protocol tables are & < > " and '. The builder here escapes them for you.
Does this fetch my sitemap?
No. You paste the file or drop it in, and it is parsed in the page. That means it works on a sitemap you have not published yet, which is when checking it is actually useful, and on a staging file that is behind a login.
Should the URLs in my sitemap have a trailing slash?
Whichever form your canonical tags use — the point is that the two agree. A sitemap listing /about while the page canonicalises to /about/ is telling a crawler to index a URL the page itself disowns. Mixed slashes in one file are flagged as a note here, not an error, because both forms are legal and the mismatch is only a problem against your canonicals.
What about image, video and hreflang sitemaps?
Those add elements from other namespaces alongside the standard ones. This reads the core schema and lists any extra elements it finds by name rather than rejecting the file, so an image sitemap validates here and you can see which extension elements are present — their contents are not read and their own rules are not checked.