← Back to the full checklist

AdSense says ads.txt is missing, but you can see the file

MONETIZATION · AdSense

AdSense reports Ads.txt status: Not found. You open the URL in a browser, and the file is right there. So which is lying?

Neither. There are two distinct causes and they need opposite responses, so identify which one you have before changing anything.

Cause one: AdSense has not crawled yet

If you added the site in the last day or two, this is almost certainly it. AdSense checks ads.txt on its own schedule, not when you add a site. The status catches up on its own. Do nothing.

Cause two: your server is serving HTML and calling it ads.txt

This is the one that matters. On many static hosts, a request for a file that does not exist does not return a 404. It returns your homepage, with a 200 OK status. Your browser renders it as a page, so opening the URL looks vaguely fine, and AdSense reads it as "this is not an ads.txt file" and reports Not found.

Telling them apart

Look at the actual bytes, not the rendered page:

curl -s https://yourdomain.com/ads.txt | head -3

You want to see this:

google.com, pub-0000000000000000, DIRECT, f08c47fec0942fa0

If instead you see <!DOCTYPE html>, the file does not exist and your host is masking that fact. Waiting will not help. No amount of patience creates a file.

Why the browser fools you: a browser asked for ads.txt, got HTML, and helpfully rendered it. It does not warn you that a plain text file came back as a web page. Only the raw response shows the truth.

The fix, and the bigger problem behind it

Add a real ads.txt file at the site root containing exactly one line, your publisher line, with no leading spaces and no HTML around it. Redeploy and re-run the curl check.

Then fix the underlying behaviour, because ads.txt is not the only thing it breaks. A host that answers every unknown path with a 200 and your homepage is also telling search engines that every typo is a real page, and it will silently defeat any code that checks whether a fetch succeeded. That failure mode gets its own guide: when a missing file returns 200 instead of 404.

Check the whole set while you are in there

The same masking hides other missing files. Run this and read the status codes, not the pages:

for f in ads.txt robots.txt sitemap.xml about contact privacy terms; do
  echo "$f -> $(curl -s -o /dev/null -w '%{http_code}' https://yourdomain.com/$f)"
done

Everything returning 200 is not necessarily good news. Compare each response against your homepage. If they are byte for byte identical, those pages do not exist.

Related