๐Ÿš€ Live Optimon AI is out of beta: ranked answers from your own live GAM and Prebid data, and a briefing every morning before you ask.Read the post โ†’

Why app-ads.txt says not found when the file is live

Crawlers find app-ads.txt from the developer website in the store listing, not from your ad code. The field to fix, the domain rule and the sellers.json check.

An embroidery hoop on a sunlit windowsill, a violet running stitch leading from a small tag to the door of the middle house in a row of three.

When app-ads.txt shows as not found while the file loads in your browser, the crawler is usually looking at a different address. It never reads your SDK or your ad requests to find the file. It reads the developer website in the Google Play or App Store listing, cuts that URL down to a root domain, and asks for /app-ads.txt there.

So the fix is often in the store console, not on the web server. This post walks through the chain the way a crawler does: the store field, the domain rule, the lines in the file, and the sellers.json lookup a buyer runs at the end.

How a crawler gets from your app to the file

A web ads.txt file is easy to find: the page is on the domain, so the file sits at the root of that domain. An app has no domain. The IAB Tech Lab app-ads.txt specification fills the gap with the store listing. The bid request carries the app's store URL (app.storeurl) and bundle ID (app.bundle). A verifier opens that listing, reads the developer website, and fetches the file from that site.

The spec asks stores to expose the developer URL, bundle ID and store ID as meta tags on the listing page, so a crawler does not have to guess. It also says verifiers should index by store and ID, its example being itunes.apple.com:343200656 => rovio.com, rather than by the full store URL, because one app has many valid store URLs.

What that means for you: the only domain that counts is the one in the store listing. If the listing says studio-games.example, a perfect file on example.com does nothing for that app.

Which store field the crawler reads

Each store keeps the developer website in a different place, and Ad Manager picks up changes at different speeds.

Store Where you set it What Google reads Time for Ad Manager to see a change
Google Play Play Console, Grow users, Store presence, Store settings, Store listing contact details The website in the listing's contact details Up to 24 hours
Apple App Store App Store Connect, platform version information, Marketing URL The marketing URL (the developer website link on the listing) Up to 7 days

Two details catch people on the Apple side. The Support URL is required and the Marketing URL is not, so a team can ship an iOS app with a support page and no marketing URL at all, and the crawler then has nothing to follow. And Apple lets you localize the Marketing URL. If your localizations carry different domains, check which one your listing shows in the markets that matter; Google's help pages do not say which localization its crawler reads.

On Google Play the website field is optional too. Play Console requires an email and recommends a website, which is how an Android app ends up live with no developer website.

The domain rule: which URL actually gets checked

Google's crawler uses only the host name of the developer website. Per the AdMob help page, for https://example.com/game it requests https://example.com/app-ads.txt and then the HTTP version. The /game path is ignored, so a file uploaded to the game's own folder is never fetched.

The other rules on the same page:

  1. A leading www. or m. is dropped. https://www.example.com/game is checked at example.com.
  2. The crawler probes at most one subdomain level. For help.example.com it tries that host first, then falls back to example.com. For support.help.example.com it starts at help.example.com.
  3. Redirects are followed, including to a www. host. If your web team can only publish under www, a redirect from the bare domain works.
  4. robots.txt applies. AdMob's troubleshooting page names Google-adstxt as the user agent, and the crawler also obeys Mediapartners-Google and Googlebot records.

The IAB spec describes the same idea in its own words: keep up to two names before the public suffix, strip www. and m., check the subdomain first and use the parent only when the subdomain has no file. Other buyers' crawlers follow the spec, not Google's help page, so a file at the bare root domain is the one location both agree on.

The lines in the file and where they come from

The file format is the same as web ads.txt: one line per seller account, with the ad system's domain, your account ID in that system, DIRECT or RESELLER, and an optional certification authority ID.

In Ad Manager the Google lines come from Admin, then Ads.txt management, then the app-ads.txt tab, then Create an ads.txt file. You need at least one linked Ad Exchange account and the Ads.txt management permission. Two warnings from Google's help page are worth acting on:

  • The generator only writes lines for Google seller accounts. Every other exchange, SSP or mediation partner has to be added by hand, from the line that partner gives you.
  • Generated rows can default to DIRECT. Change a row to RESELLER when you do not own and operate the inventory, for example when a partner sells on your behalf under its own account.

AdMob's troubleshooting page lists the formatting mistakes it sees most: a missing or malformed publisher ID, a typo in the ID, and admob.com written where google.com belongs. Copy Google's line from the console rather than typing it.

Reading the status in Ad Manager

The app-ads.txt tab shows one of four statuses per domain:

Status What it means First thing to check
No ads.txt/app-ads.txt file found No file at that domain at the last crawl The developer website in the listing, then the root URL and robots.txt
No seller accounts authorized A file exists but lists none of your linked Ad Exchange accounts The publisher ID on the google.com line
Some seller accounts authorized Only part of your linked accounts are listed Accounts added since the file was made
All seller accounts authorized Every linked account is in the file Nothing for Google; check your other partners' lines

The status reflects the last crawl, and the View or Fix link shows the copy of the file Google fetched, which can be older than what is on your server. Ad Manager says the crawler tries each file every 24 hours, and that a file posted more than 48 hours ago that still shows as not found usually means Google cannot crawl or parse it. AdMob adds one more case: an app that has made no ad request in the last seven days may show no status at all, which is a quiet app, not a broken file.

The last step: what a buyer does with sellers.json

app-ads.txt tells a buyer which accounts may sell your app. sellers.json tells them who those accounts belong to. A buyer takes the account ID from a line in your file and looks it up in the ad system's sellers.json. For your Google line, that is your publisher ID in Google's file.

Publishers do not write that file; each ad system publishes its own. Your part is a setting. In Ad Manager, under Global settings and Ad Exchange account settings, Sellers.json transparency decides whether your name and domain appear next to your ID. When the account is confidential, the ID stays and the name and domain are left out. Google also notes that the domain only shows once Google has verified it, and that the transparency setting is shared across AdSense, AdMob and Ad Manager.

For an app, the domain in your sellers.json entry and the developer website in your store listing should agree. Neither Google nor the IAB spec makes that a hard rule, but a buyer who sees a listing on one domain and a seller entry on another has a reason to bid less or not at all.

What to check tomorrow morning

Pull the list once and walk each app through the chain:

  1. In Ad Manager, open Admin, then Ads.txt management, then the app-ads.txt tab, and filter for any status other than All seller accounts authorized.
  2. For each domain, open the app's Google Play and App Store listings and copy the developer website exactly as shown.
  3. Reduce it by hand: host name only, no www. or m., at most one subdomain. Run curl -sI https://<that domain>/app-ads.txt and expect a 200 with a text content type, then open the file and find your google.com line with your publisher ID.
  4. If the store field is wrong or empty, fix it in Play Console or App Store Connect, then wait a day for Android and up to a week for iOS before you read the status again.
  5. Check that every non-Google partner on your mediation stack has its line in the same file.

If app revenue moved and you are not sure whether a file or demand is behind it, Optimon reads your own GAM and Prebid data and explains what moved and why, with the numbers.

FAQ

Where does Google look for my app-ads.txt file?

It takes the developer website from your Google Play or App Store listing, keeps only the host name, drops a leading www. or m., and requests /app-ads.txt at the root of that domain over HTTPS, then HTTP. The path in the website URL is ignored, so a file under /apps/ or /games/ is never read.

How long does a fix take to show in Ad Manager?

Ad Manager says to allow up to 24 hours for a changed developer website on Google Play to be picked up and up to 7 days on the App Store. The crawler then tries the file about once a day. Plan for a day on Android and up to a week on iOS before you judge the status.

Do I need sellers.json for app-ads.txt to work?

You do not publish a sellers.json file as a publisher; your ad systems do. A buyer matches the account ID on your app-ads.txt line with the seller ID in that system's sellers.json. If your Google account is confidential, buyers still see the ID but not your name or domain, so the match works but tells them less.

Sources

Contact

Let's talk yield.

Whether you want a demo, a free audit, or just want to ask us something - we're a real team that reads every email.

Response time

We reply to every message within one business day. Enterprise enquiries typically get a call scheduled same-day.

Direct line

Prefer email? hello@optimon.io

Not sure where to start?

Drop your domain into the homepage scanner. We'll show you what we find before you commit to anything.

Free scan โ†’