"XML declaration allowed only at the start of the document": removing the stray output that breaks your sitemap
This error means something was sent to the browser before <?xml. XML requires the declaration to be the first bytes of the document, so one blank line or an invisible byte-order mark makes the whole sitemap unreadable. The culprit is nearly always a PHP file with characters outside its <?php tags.
Chrome words it as "error on line 2 at column 6: XML declaration allowed only at the start of the document". Firefox says "XML or text declaration not at start of entity". Both describe the same fault, and it breaks RSS feeds on the same site in the same way.
What it looks like
Before
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
After
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
See the offending bytes
The line number in the browser message tells you how many line breaks precede the declaration: "line 2" means one. To see exactly what is there:
curl -s https://example.com/sitemap.xml | head -c 16 | xxd
0aor0d 0abefore3c 3f 78 6d 6c(<?xml) is a newline.20is a space,09a tab.ef bb bfis a UTF-8 byte-order mark, which no text editor shows on screen.
If the output starts with readable text, such as a PHP "Warning:" or "Deprecated:" message, the cause is different and simpler: error display is on. Set WP_DEBUG_DISPLAY to false in wp-config.php so notices go to the log instead of the page.
Where the stray characters come from
PHP sends anything outside <?php ... ?> straight to the output. Every PHP file loaded on the request is a candidate:
- A blank line or space before the opening
<?phpon line 1. - Anything after a closing
?>at the end of a file. This is why WordPress coding standards omit the closing tag in pure PHP files. - A file saved as "UTF-8 with BOM", typically after being edited in a Windows text editor.
- A plugin or snippet that echoes output early, for instance a debugging
echoor an inline script printed oninit.
The files most often responsible are the ones people edit by hand: wp-config.php, the active theme's functions.php, and custom or "code snippet" plugins.
Find the file
Start with the hand-edited files. Open each, put the cursor at the very top and very bottom, and delete any blank lines outside the PHP tags. If the file ends with ?>, remove that tag.
For byte-order marks, search from the command line in the WordPress root:
grep -rl $'\xEF\xBB\xBF' --include="*.php" wp-content wp-config.php
Files that begin with something other than the opening tag can be listed with:
find wp-content -name "*.php" -exec sh -c 'head -c 5 "$1" | grep -q "^<?php" || echo "$1"' _ {} \;
It prints every PHP file whose first five bytes are not <?php. Template files that begin with HTML will appear in the list legitimately; look for files that should be pure PHP.
If you have no shell access, bisect instead: switch to a default theme and reload the sitemap. If the error persists, deactivate half the plugins, reload, and narrow it down from there.
Repair it
Remove the whitespace, delete trailing ?> tags, and re-save BOM-affected files as "UTF-8" without a signature (most editors offer this under encoding or "Save with encoding"). Replace an affected plugin or theme file with a clean copy from its original package when the edit was accidental.
Then clear every cache that might hold the broken response: the page cache, any server cache and the CDN. Hydrogen SEO rebuilds its own sitemap cache when content or sitemap settings change, and saving the Sitemap screen refreshes it on demand, but an outer cache can keep serving the old bytes. More sitemap diagnostics are in sitemap troubleshooting.
Make sure it is gone everywhere
- Repeat the
xxdcommand. The first bytes should be3c 3f 78 6d 6c. - Load the sitemap index and one child sitemap in a browser; both should render without a yellow or pink error box.
- Load your feed at
/feed/, which fails from the same cause. - Paste the sitemap into the XML sitemap validator for a protocol check.
- In Search Console, resubmit the sitemap if its status had changed to an error.
Common questions
Is this a bug in my sitemap plugin?
Almost never. The sitemap code prints valid XML; another file loaded earlier in the request printed characters first. Any XML the site serves is affected.
Why does my site look normal if a file is printing extra whitespace?
HTML ignores leading whitespace, so pages render fine. XML does not allow it, which is why only sitemaps and feeds break.
Can I just strip the whitespace with output buffering?
Workarounds exist that buffer and trim output, but they hide a fault that can also cause "headers already sent" warnings and broken redirects. Fixing the file is safer.
Does Google read a sitemap with this error?
It may fail to parse it and report an error for the sitemap in Search Console. Treat it as unread until the declaration is the first thing in the response.