Shipping notes
AdMob says “No ad to show” on your brand new app. Here is why, and how long it actually lasts.
Linking your store listing is only half of it — and the console never tells you that. This is the two-gate process spelled out, plus the day-by-day timeline from a real launch.
Short version
A new AdMob app sits in a state called limited ad serving and receives close to zero inventory until Google verifies it. Clearing it takes two separate steps, and the console only ever shows you the next one, so it reads like a single task. After both are done you still wait for Google’s crawler. On my launch that wait was five more days. Near-zero fill in your first week is the expected state, not a bug you can debug your way out of.
The symptom
Real ad unit ids. No errors in the log. Everything wired correctly. Every single request comes back No ad to show, and you get maybe one impression a day — on your own phone.
Then you swap in the test ad unit ids and they fill instantly, every time. Which is exactly the observation that convinces you your integration is fine and the problem must be somewhere stranger. I spent two days there. The integration was fine. The problem was account-side, and none of it is visible from the SDK.
This is engine-independent. I hit it in Unity, but everything below is console-side and applies the same to native Android, native iOS, Flutter or anything else.
What is actually happening
A brand new app in AdMob is placed in limited ad serving. Advertisers do not bid meaningfully on unverified inventory, so you get a trickle instead of a fill rate. Lifting it requires two things, and the console shows them one at a time, as a single line of status text that changes underneath you.
Gate 1 — link the app to its store listing
App settings → App store details → Add. Two traps here:
- Searching by package name or bundle id finds nothing for a freshly published app, because AdMob has not indexed it yet. This looks like your app is somehow not on the store. It is. Search by the full store URL instead — paste the Play or App Store link and it resolves immediately.
- Doing this does not lift the limit. It only changes the status text from “Add store to lift limit” to “Verify app to lift limit”. I read the first message, completed the task it asked for, watched the warning stay on screen, and assumed I had done everything. I had not. This is the single point where most people stop.
Gate 2 — verify the app with app-ads.txt
Verification wants an app-ads.txt file, and it is specific about where:
- It must be on the developer website listed on your store page — not wherever else you happen to host things. Google reads the store listing to find out which domain to trust, so if your listing points at
example.com, the file has to be onexample.com. - It must be at the root of that exact domain:
https://example.com/app-ads.txt. Not in a subfolder, and watch out for awwwversus bare-domain mismatch against what your listing says. - The publisher id line has to match your account exactly, in the standard format:
google.com, pub-0000000000000000, DIRECT, f08c47fec0942fa0.
Then you wait, and there is no button that helps
This is the part I could not find written down anywhere, and the reason I am writing this post.
Even with the file live, correct, and on the right domain, nothing moves until Google’s crawler picks it up. The console says up to 7 days. Check for updates does not force a crawl — it re-reads whatever Google already has. There is no appeal to file, no support ticket that speeds it up, and nothing in your build to change.
The measured timeline
Day 1 — store link added on both apps, app-ads.txt confirmed live on the correct domain and returning HTTP 200. Status stayed at limited ad serving.
Days 2–5 — single-digit impressions per day. No change, despite checking constantly.
Day 6 — both apps flipped to Ad serving enabled. I changed nothing in between. Same build, same ad units, no code change, no resubmission.
For scale, the week that followed the flip:
| Metric | First 7 days after serving was enabled |
|---|---|
| Requests | 812 |
| Impressions | 488 |
| Match rate | 88% |
Before the flip that same number was in the single digits per day. So if you are staring at a match rate near zero in week one, the honest answer is that you are probably not doing anything wrong — you are early.
Two things worth planning around during that window
Your rewarded ad path will look broken to anyone watching
If you have a rewarded placement — continue after death, unlock a car, double a reward — the player taps Watch ad and nothing happens. Mine is designed to fall through to the non-reward outcome rather than block the game on ad availability, which I still think is correct behaviour. But to an observer it is indistinguishable from a dead button.
That matters more than it sounds, because the observers in your first week are exactly the people you cannot afford to confuse: store reviewers, the first players who write to you, and yourself while you are recording trailer footage. Keep the ad path out of demo videos until serving is enabled.
Do not replay your own ads to check they work
Once you are off test ids, watching your own live ads is invalid traffic, and it gets accounts suspended. “I was only testing” is not a defence, and there is no meaningful appeal. If you need to see a real ad unit behave on hardware, register the device first with RequestConfiguration.TestDeviceIds so your impressions are excluded.
One more source of confusion: two different “limited ad serving”
There are two unrelated states with almost the same name, and threads about them get mixed together constantly:
- Publisher side (AdMob) — everything in this post. You are showing ads, and your inventory is throttled until the app is verified.
- Advertiser side (Google Ads) — you are buying ads, and a new advertiser account is throttled until advertiser identity verification is completed. That one is a form you have to submit; waiting alone does not clear it.
They have different causes and different fixes. Worth checking which console the warning is actually in before acting on advice written for the other one. Similarly, a policy violation and a serving limit are two separate rows: appealing the violation does not lift the limit, and clearing the limit does not resolve the violation.
Checklist, in order
- Publish the app and let the store listing go live.
- In AdMob, add the store listing by pasting the store URL, not by searching the package name.
- Note that the warning text changed rather than disappeared. You are halfway.
- Put
app-ads.txtat the root of the developer website named on your store listing, with your publisher id line. - Confirm it returns HTTP 200 from the outside, on the exact domain the listing points to.
- Wait. Expect several days. Do not change your build looking for a fix.
- Meanwhile: avoid the ad path in demo footage, and register your own device as a test device.
Slide2Go
All of the above came out of shipping this: a sliding block puzzle where dragging one block pushes every block it is touching, so a single drag can shift an entire row. Free on both stores, plays offline.
