XML sitemap (sitemap.xml): what to include, common errors and how to check it
SEOAudit7 min read
An XML sitemap is a file that lists the URLs you want search engines to discover. It usually lives at /sitemap.xml in the root of the site. It takes minutes to write and is surprisingly easy to spoil: add redirects, blocked pages or addresses on the wrong host, and search engines learn to trust the file less.
This guide covers what the file must contain, which fields matter, how to describe language versions and which mistakes show up most often. It ends with a short routine you can run in about ten minutes. A sitemap helps pages get found. It does not guarantee crawling, indexing or rankings.
What a sitemap is and what it can do
The XML format is defined by the protocol on sitemaps.org. It is a UTF-8 list of addresses, each of which can carry a last-modified date. Search engines read it as a hint: these are the pages we consider important.
The limits of that hint matter. A sitemap helps discovery, especially on large sites, new domains and sites with few internal links. But listing a URL does not force Google to crawl it, and it certainly does not force indexing. If a page is thin, duplicates another one or is blocked from indexing, the sitemap changes nothing.
A small site with good internal linking can live without one. Still, it is cheap insurance: the file can be generated automatically, and Google Search Console reports how many of the listed URLs it found. So every public site benefits from a sitemap, as long as someone keeps it accurate. For the wider picture of technical checks, see the technical SEO checklist.
A minimal file and the rules it must follow
The simplest valid sitemap looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
<lastmod>2026-10-24</lastmod>
</url>
<url>
<loc>https://example.com/pricing</loc>
<lastmod>2026-09-02</lastmod>
</url>
</urlset>Only loc inside url is required. The rules from the protocol:
- the file is UTF-8 and special characters in URLs are escaped (
&instead of&); - URLs are absolute, with protocol and host:
https://example.com/page, not/page; - one file holds at most 50,000 URLs and at most 50 MB uncompressed;
- the file may be compressed as
.xml.gz, but the 50 MB limit applies to the uncompressed content; - a sitemap placed in a subdirectory may only describe URLs in that directory and below.
Protocol and host in the listed URLs must match the site. If the site runs on https://example.com, entries with http:// or www. are mistakes.
Which URLs to include and which to leave out
The rule is simple: list only the URLs you want in the index. Each one should meet a few conditions.
- It answers with status 200. No redirects, no 404s.
- It is indexable: no
noindexin the meta tag or in theX-Robots-Tagheader. - It is the canonical address. If a page points its canonical at another URL, the sitemap should list that other URL. The canonical tag guide explains how.
- It is not blocked in robots.txt. Otherwise you ask crawlers to find a page and forbid them to open it. The robots.txt guide shows how to write the rules.
- It is not a utility address: site search results, filter combinations with parameters, cart pages, drafts.
What usually gets listed by mistake
Pagination that the CMS adds automatically, tag archives with a single post, duplicates with ?utm_source= parameters and thank-you pages after forms are the usual suspects. If you doubt that a page belongs in search, it does not belong in the sitemap either.
Separate protocol extensions exist for images, video and news. Use them only if such content matters to your business.
The lastmod field, and why priority and changefreq can go
The lastmod field holds the date of the last significant change to the page, in W3C datetime format: 2026-10-24 or a full timestamp with time zone. According to Google's documentation, it uses the value only when it is consistently and verifiably accurate. In other words, if the date really tracks content changes, it can help decide what to recrawl.
A common mistake is to put the build date into lastmod. Then every deploy refreshes every URL, including pages untouched for months. Search engines notice that the signal does not match reality and stop believing it.
What counts as a significant change: new text, a changed price, a restructured page, updated structured data. Fixing a typo or editing the footer usually does not.
Google ignores priority and changefreq, and says so in its documentation. You may keep them if another system requires them, but do not expect any effect on search. A file without them is no worse.
If you have no reliable dates at all, it is better to omit lastmod than to fill in today's date.
Large sites and the sitemap index
When you pass 50,000 URLs or 50 MB, the file has to be split. You create an index file that points to the individual sitemaps:
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://example.com/sitemap-pages.xml</loc>
<lastmod>2026-10-24</lastmod>
</sitemap>
<sitemap>
<loc>https://example.com/sitemap-blog.xml</loc>
<lastmod>2026-10-20</lastmod>
</sitemap>
</sitemapindex>Splitting is useful even before you hit a limit. Separate files for pages, blog posts and products let you see in Search Console which group of URLs has a problem. The index file can be listed in robots.txt and submitted to Search Console just like a normal sitemap, and the child files do not need to be submitted again. Details are in Google's documentation on large sitemaps.
For a small site with a few dozen pages, a single file is plenty. Do not add structure you do not need.
Language versions: hreflang inside the sitemap
On a multilingual site you can describe the links between versions in the sitemap instead of in the page head. You declare the xhtml namespace, and every url entry lists all alternates, itself included. Here is an example with an Ukrainian version at the root plus /en and /es:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://example.com/pricing</loc>
<xhtml:link rel="alternate" hreflang="uk" href="https://example.com/pricing"/>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/pricing"/>
<xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/pricing"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing"/>
</url>
<url>
<loc>https://example.com/en/pricing</loc>
<xhtml:link rel="alternate" hreflang="uk" href="https://example.com/pricing"/>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/pricing"/>
<xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/pricing"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing"/>
</url>
<url>
<loc>https://example.com/es/pricing</loc>
<xhtml:link rel="alternate" hreflang="uk" href="https://example.com/pricing"/>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/pricing"/>
<xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/pricing"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing"/>
</url>
</urlset>The key rule is reciprocity: if page A points to B, B must point back to A. The code for Ukrainian is uk, not ua. The remaining typical mistakes, x-default included, are collected in the hreflang guide. Avoid maintaining two methods for the same page without a reason: head tags or sitemap entries are enough.
Common sitemap errors
These turn up most often.
- Stale URLs. A page was deleted or moved but stayed in the file. The crawler gets a 404 or a redirect and trusts the whole list less.
- Wrong protocol or host. The site moved to HTTPS, yet the sitemap still lists
http://. The same goes forwwwversus the bare domain. - Build date instead of change date. Described above: every
lastmodis identical and refreshed on each deploy. - Blocked URLs. Pages with
noindexor pages disallowed in robots.txt should not appear in the file. - Parameter URLs. Filters, sorting and session identifiers create hundreds of duplicates.
- HTML instead of XML. At
/sitemap.xmlthe server returns a 404 page with status 200 (a soft 404) or redirects to the home page. To a visitor it looks like a page, to a crawler it is a broken file. - Oversized file. More than 50,000 URLs or 50 MB, so part of the entries is ignored.
- Nobody knows about it. The file exists, but it is neither in robots.txt nor in Search Console.
How to announce the sitemap
Besides Search Console, the easiest way is a line in robots.txt:
User-agent: *
Disallow: /admin/
Sitemap: https://example.com/sitemap.xmlThe Sitemap line does not belong to any User-agent group and must contain a full absolute URL.
How to check a sitemap in ten minutes
You do not need expensive tools. Follow this routine.
- Open the file in a browser. You should see XML, not a page of the site.
- Check the response headers with
curl -I https://example.com/sitemap.xml. Expect status 200 and an XML content type:
HTTP/2 200
content-type: application/xml- Add the file to the Sitemaps report in Google Search Console and compare the number of submitted URLs with the number discovered. A big gap is a reason to dig.
- Pick five to ten URLs from different parts of the file, open them and confirm they return 200, carry no noindex and have a canonical pointing at themselves.
- Make sure the sitemap is declared in robots.txt.
The free scanner automates part of this. It looks for a sitemap at /sitemap.xml and in one same-host sitemap declared in robots.txt, and reports a file that is missing, empty, undeclared or without lastmod. It also flags http or foreign-host URLs and requests three URLs from the file (the first, the middle and the last) to see whether they answer. It is passive: it reads at most 200 KB of the file, does not validate it against the schema and does not crawl every address. Treat it as a quick review, not a replacement for Search Console. The scan is part of the SEO audit, security topics sit in the security check, and the AI visibility page covers readiness for AI search.
A good sitemap is short and honest: canonical pages with status 200, accurate dates, a declaration in robots.txt and a regular check. Run your own file through the free scanner and fix what it reports.
Frequently asked questions
- Is a sitemap.xml required for a website?
No, search engines can also find pages through links. But for new sites, large sites and pages with few internal links, the file noticeably helps discovery. It is cheap to maintain, so it is worth having. It does not guarantee indexing.
- Do I need priority and changefreq?
No. According to Google's documentation these fields are ignored. You can keep just
locand an accuratelastmod. If another system requires the fields you may leave them in, but do not expect any effect on search.- How many URLs can one sitemap hold?
The sitemaps.org protocol allows up to 50,000 URLs and 50 MB uncompressed per file. Beyond that, create an index file that points to several sitemaps. For small sites one file is enough, and splitting by page type makes diagnosis in Search Console easier.
- Why does Search Console show fewer discovered URLs than the file contains?
Usually some URLs redirect or return errors, are blocked by noindex or robots.txt, or the file contains duplicates. Open a few URLs from different parts of the file and check the status code, canonical and meta tags. Sometimes Google simply has not processed the whole file yet.