Opens in a new tab
  1. Home
  2. Guides
  3. Utilities
Utilities guide

How to Check if your ads.txt File is Being Served Correctly

Learn how to verify that your WordPress ads.txt file is publicly accessible and correctly served, including HTTP status codes, plain-text headers, apex and www behavior, HTTP and HTTPS redirects, robots.txt restrictions, CDN caching, physical-file conflicts and seller-record validation.

  • Updated September 22, 2026
  • 25 min read
  • WordPress guide

Checking if your ads.txt file is being served correctly means verifying more than simply opening /ads.txt in a browser and seeing some text.

A correctly served ads.txt endpoint should normally satisfy several independent checks:

Correct URL
→ /ads.txt

Reachable from the root domain
→ yes

HTTP response
→ successful

Google recommendation
→ 200 OK

Content-Type
→ text/plain

Content
→ valid ads.txt records

Crawler access
→ not blocked

HTTP / HTTPS behavior
→ consistent and reachable

Redirects
→ valid and intentional

A browser can make a broken configuration appear healthy because it automatically follows redirects, caches previous responses and renders error pages that may still return HTTP 200.

Advertising crawlers do not evaluate the page visually. They evaluate:

  • the URL;
  • HTTP status;
  • redirect chain;
  • response headers;
  • robots.txt accessibility;
  • plain-text contents;
  • ads.txt syntax.

This guide explains how to verify that a WordPress ads.txt file is being served correctly, how to inspect its HTTP response, how to identify physical and virtual file conflicts, how to troubleshoot redirects, caching, CDN behavior and robots.txt restrictions, and how to distinguish a technically reachable file from a correctly configured authorized-seller declaration.

What does “served correctly” mean for ads.txt?

An ads.txt implementation has several layers.

1. Discovery
→ crawler finds /ads.txt

2. HTTP delivery
→ server successfully returns it

3. File format
→ plain text is served

4. Syntax
→ records can be parsed

5. Business data
→ seller IDs are correct

A problem at any one of these layers can make the implementation ineffective.

A file can load in your browser and still be wrong

Suppose you open:

https://example.com/ads.txt

and see:

google.com, pub-1234567890123456, DIRECT

That is a useful first check.

It does not prove that:

  • the response status is correct;
  • the MIME type is correct;
  • HTTP also resolves correctly;
  • the root domain can discover it;
  • robots.txt permits crawling;
  • the publisher ID is correct;
  • a CDN is not serving stale content;
  • another physical file is overriding WordPress;
  • Google has already recrawled the file.

Step 1: open the standard ads.txt URL

For a normal domain:

https://example.com

the file should be reachable at:

https://example.com/ads.txt

not:

https://example.com/wp-content/ads.txt

https://example.com/files/ads.txt

https://example.com/ads/ads.txt

https://example.com/ads.txt/

The IAB Tech Lab ads.txt specification defines /ads.txt as the standard relative path.

ads.txt belongs at the root domain

The IAB specification defines the root domain using the registrable-domain concept based on the public suffix.

For a normal website such as:

www.example.com

the root domain is typically:

example.com

and the discovery process starts from:

example.com/ads.txt

Do not confuse the WordPress installation directory with the domain root

WordPress may physically live in:

/var/www/example/public/

or

/public_html/

or

/wordpress/

but advertising crawlers care about the public URL:

https://example.com/ads.txt

not where the corresponding data happens to be stored on the server.

ads.txt does not need to be a physical file

The IAB specification explicitly allows the /ads.txt resource to be generated without originating from a physical filesystem file.

That means WordPress can legitimately serve:

/ads.txt

through:

  • a rewrite rule;
  • a plugin;
  • application logic;
  • a reverse proxy;
  • a dynamically generated response.

The public HTTP behavior matters more than whether:

ads.txt

exists as a literal file on disk.

TheOneWP Ads.txt & App-ads.txt Editor uses this virtual-file approach to expose the saved content at the standard public URLs.

Step 2: check the HTTP status code

Do not stop at the browser.

Inspect the HTTP response directly.

With curl:

curl -i https://example.com/ads.txt

A healthy response may begin with:

HTTP/2 200

content-type: text/plain; charset=UTF-8

followed by the ads.txt content.

Google recommends HTTP 200 OK

Google’s official ads.txt crawler troubleshooting documentation recommends that the ads.txt endpoint return:

200 OK

This is the simplest response for a final canonical ads.txt resource.

The IAB specification accepts successful 2xx responses

The current IAB ads.txt specification describes successful:

HTTP 2xx

responses as readable ads.txt resources.

For practical WordPress deployments, however, returning:

200 OK

for the final resource is the clearest configuration and aligns with Google’s troubleshooting recommendations.

A 404 means the resource was not found

If:

curl -i https://example.com/ads.txt

returns:

HTTP/2 404

the file is not being served at that URL.

Common causes include:

  • no physical file exists;
  • the WordPress virtual endpoint is not active;
  • rewrite rules were not registered;
  • the WordPress module is disabled;
  • no ads.txt content has been configured;
  • the request is reaching the wrong virtual host.

A 200 response can still be a soft 404

A poorly configured server might return:

HTTP 200

while the body contains:

<html>
    <h1>Page not found</h1>
</html>

That is not a valid ads.txt response.

Always inspect:

status
+
headers
+
body

Check the response body

The body should contain ads.txt records, comments or supported variable declarations.

A normal seller record has the structure:

advertising-system-domain,
publisher-account-id,
relationship,
optional-certification-id

For example:

example-ad-system.com, 123456, DIRECT

or:

example-ad-system.com, 123456, RESELLER

For the complete setup process, see How to Set Up ads.txt for WordPress.

Step 3: verify the Content-Type

The ads.txt specification defines the resource as plain text.

The expected response header is:

Content-Type: text/plain

A UTF-8 charset can also be declared:

Content-Type:
text/plain; charset=utf-8

Check headers without printing the complete body

You can use:

curl -sS \
    -D - \
    https://example.com/ads.txt \
    -o /dev/null

Look for:

HTTP/2 200

content-type: text/plain

Why not rely only on curl -I?

You will often see:

curl -I https://example.com/ads.txt

recommended for header testing.

This sends an HTTP:

HEAD

request rather than a normal:

GET

request.

Well-configured servers should normally return equivalent metadata, but applications and proxies can occasionally handle HEAD differently.

For definitive testing, use a normal GET request and inspect its headers.

HTML is not valid ads.txt output

If the response starts with:

<!doctype html>

or:

<html>

something is wrong.

Possible causes include:

  • WordPress serving a theme template;
  • a 404 template returning 200;
  • a security challenge;
  • a maintenance page;
  • a login page;
  • a CDN challenge;
  • an incorrect redirect destination.

Do not serve ads.txt through a normal WordPress Page

Creating a WordPress Page called:

ads.txt

is not equivalent to serving a proper ads.txt resource if WordPress renders the page using the normal theme.

A theme response may contain:

HTML
header
navigation
footer
scripts
styles

ads.txt needs a plain-text endpoint.

Step 4: inspect redirects

Your browser may silently follow:

http://example.com/ads.txt
↓
https://example.com/ads.txt
↓
https://www.example.com/ads.txt

and show only the final file.

Inspect the chain explicitly.

Use curl to follow redirects

curl -L -i \
    http://example.com/ads.txt

The:

-L

option tells curl to follow redirects.

Inspect only the redirect headers

curl -sS \
    -L \
    -D - \
    http://example.com/ads.txt \
    -o /dev/null

You might see:

HTTP/1.1 301 Moved Permanently
Location: https://example.com/ads.txt

HTTP/2 200
Content-Type: text/plain

This is a normal HTTP-to-HTTPS redirect pattern.

Redirects inside the same root domain are supported

The ads.txt 1.1 specification allows redirects that remain within the original root-domain scope.

This makes configurations such as:

example.com/ads.txt
↓
www.example.com/ads.txt

possible when correctly implemented.

External redirects have stricter rules

The IAB specification permits only a single redirect outside the original root domain for delegation to another web server.

If that external destination then redirects again, the response should be treated as an error by compliant consuming systems.

Therefore this deserves scrutiny:

example.com/ads.txt
↓
thirdparty.example/ads.txt
↓
other.example/ads.txt

Keep the redirect path simple

For most WordPress websites, the cleanest configuration is:

http://example.com/ads.txt
↓
https://example.com/ads.txt
↓
200 plain text

or:

example.com/ads.txt
↓
www.example.com/ads.txt
↓
200 plain text

A complicated redirect chain provides very little benefit.

Step 5: test the apex domain and www separately

Suppose the main website uses:

https://www.example.com/

Do not test only:

https://www.example.com/ads.txt

Also test:

https://example.com/ads.txt

Google specifically notes that discovery begins from the root domain.

If www hosts the file, the root domain should reach it

A common working architecture is:

https://example.com/ads.txt
↓
301
↓
https://www.example.com/ads.txt
↓
200

If instead:

https://example.com/ads.txt
→ 404

while:

https://www.example.com/ads.txt
→ 200

some crawlers may have difficulty discovering the intended file.

Test all relevant host variants

A useful checklist is:

https://example.com/ads.txt

https://www.example.com/ads.txt

http://example.com/ads.txt

http://www.example.com/ads.txt

Not every version needs to return the file directly.

They should resolve predictably to the canonical implementation where appropriate.

Step 6: test both HTTP and HTTPS

Google’s ads.txt crawler documentation recommends ensuring that the resource is reachable through both:

HTTP
and
HTTPS

This does not mean maintaining separate files.

A normal secure website should usually redirect:

HTTP
↓
HTTPS

Example

http://example.com/ads.txt
↓
301

https://example.com/ads.txt
↓
200

That provides one canonical ads.txt response while still allowing the HTTP URL to resolve.

Check HTTPS certificate behavior

If:

https://example.com/ads.txt

fails because of:

  • expired certificate;
  • hostname mismatch;
  • broken TLS chain;
  • unsupported TLS configuration;

the file is not reliably accessible even if HTTP works.

Use curl to detect TLS problems

curl -v \
    https://example.com/ads.txt

Do not use:

-k

as your normal verification method because that tells curl to ignore certificate validation errors.

If the endpoint only works with:

curl -k

fix the TLS configuration.

Step 7: confirm robots.txt does not block ads.txt

Open:

https://example.com/robots.txt

and review the crawl directives.

Google warns that an ads.txt resource can be ignored when crawling is disallowed by robots.txt.

Example of a problematic rule

User-agent: *
Disallow: /ads

That path can match:

/ads.txt

and interfere with crawler access.

Also check crawler-specific rules

A robots.txt file could contain:

User-agent: Googlebot
Disallow: /

or another rule affecting the crawler involved in discovery.

The exact effect depends on the crawler and rule set.

For the wider role of robots.txt, see What Is robots.txt and Why Does It Matter for SEO?.

WordPress can serve robots.txt virtually too

Just as ads.txt does not need to be a physical file, WordPress can provide a virtual robots.txt response.

Physical and virtual resources can interact differently with the web server.

See WordPress’s Virtual robots.txt vs. a Physical File for the same architectural distinction applied to robots.txt.

Step 8: verify the file is actually plain text

A normal ads.txt body might look like:

# Authorized advertising systems

example-ad-system.com, 123456, DIRECT
another-system.example, abc789, RESELLER

It should not contain:

<p>
<br>
<div>
<html>
<script>
<style>

Do not paste rich-text formatting into ads.txt

Google specifically recommends using plain text because rich-text editors can introduce:

  • unexpected formatting;
  • invalid characters;
  • non-standard whitespace;
  • hidden metadata.

Use a plain-text editor or a dedicated ads.txt editor.

Check for invalid characters

Invisible characters can be difficult to identify visually.

Potential problems include:

  • non-breaking spaces;
  • smart punctuation;
  • invalid UTF-8 sequences;
  • unexpected control characters.

Inspect the raw response

Download it:

curl -sS \
    https://example.com/ads.txt \
    -o ads.txt

Then inspect the file in a plain-text or code editor.

Check UTF-8 where necessary

The IAB specification states that:

text/plain; charset=utf-8

can be used to explicitly signal UTF-8 support.

Simple ASCII-compatible seller records generally avoid encoding complexity entirely.

Step 9: validate each seller line

A technically perfect HTTP endpoint can still contain invalid ads.txt records.

The primary record structure is:

FIELD 1
Advertising system domain

FIELD 2
Publisher account ID

FIELD 3
DIRECT or RESELLER

FIELD 4
Optional certification authority ID

Example

google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0

Do not copy that placeholder publisher ID into production.

Your actual advertising platform must provide the seller-account identifier you should publish.

Field 1: advertising system domain

The first field should identify the canonical domain of the advertising system.

For example:

google.com

Do not replace it with:

  • your own website domain;
  • an arbitrary corporate homepage;
  • the ad network’s dashboard URL;
  • a URL containing https://.

Field 2: publisher account ID

The second field identifies the relevant seller or publisher account inside the advertising system.

This value must match what the platform expects.

For Google AdSense, Google tells publishers to compare the value against the publisher ID shown in their AdSense account.

A typo in the ID is not an HTTP problem

This file:

google.com, pub-WRONG-ID, DIRECT

can still return:

200 OK
Content-Type: text/plain

and remain semantically wrong.

This is why delivery verification and content verification are separate tasks.

Field 3: DIRECT vs RESELLER

The IAB specification defines:

DIRECT

when the publisher directly controls the account represented in field 2 on the advertising system.

It defines:

RESELLER

when another entity is authorized to control that seller account and resell the inventory.

Do not guess this field.

Use the line supplied or documented by the advertising partner.

Field 4 is optional

The fourth field can contain a certification authority identifier associated with the advertising system.

A three-field line can therefore be valid:

example.com, 12345, DIRECT

as can a correctly populated four-field record:

example.com, 12345, DIRECT, abcdef123456

Comments are supported

Lines beginning with:

#

are treated as comments.

For example:

# Google

google.com, pub-1234567890123456, DIRECT

Comments can make larger files easier for administrators to maintain.

Comments do not authorize sellers

This:

# google.com, pub-1234567890123456, DIRECT

is a comment.

It is not an active seller record.

ads.txt 1.1 also supports variable declarations

The current IAB standard supports declarations including:

OWNERDOMAIN=

MANAGERDOMAIN=

These are separate from ordinary authorized-seller records.

Use them only when they accurately describe your inventory ownership or management structure.

Step 10: check for duplicate or conflicting entries

Large ads.txt files can accumulate duplicate lines over time.

For example:

example.com, 123, DIRECT
example.com, 123, DIRECT

A duplicate may not necessarily make the complete file unreadable, but it adds unnecessary maintenance noise.

Conflicting relationship values deserve investigation

This is more concerning:

example.com, 123, DIRECT
example.com, 123, RESELLER

Determine which relationship is actually correct.

Do not automatically deduplicate by account ID alone

Different advertising systems can use similar or identical account-ID formats.

Treat the record as a combination of:

advertising system
+
account ID
+
relationship

rather than comparing field 2 in isolation.

Step 11: compare the live response with what you saved

This is particularly important on WordPress.

Suppose your administration screen contains:

google.com, pub-NEW-ID, DIRECT

but the public endpoint still shows:

google.com, pub-OLD-ID, DIRECT

The editor may be working perfectly while another delivery layer serves stale or conflicting content.

Possible causes include a physical ads.txt file

A web server usually serves a real:

/ads.txt

file before the request ever reaches WordPress rewrite logic.

This can create:

WordPress editor
→ new content

physical ads.txt
→ old content

public request
→ physical file wins

Check the WordPress document root

Look for a real file named:

ads.txt

in the public WordPress root.

Common locations include:

/public_html/ads.txt

/htdocs/ads.txt

/public/ads.txt

depending on hosting configuration.

TheOneWP checks for a physical file conflict

TheOneWP Ads.txt & App-ads.txt Editor serves its configured content virtually.

When a physical:

ads.txt

or:

app-ads.txt

exists in the WordPress root, the web server can serve that physical resource before WordPress handles the request.

The module therefore treats physical-file presence as a conflict that should be resolved before relying on its virtual endpoint.

Decide who owns ads.txt

A site should have a clear source of truth:

physical file
or
WordPress virtual endpoint

not:

physical file
+
plugin A
+
plugin B
+
CDN rule
+
hosting injection

all competing for the same URL.

Step 12: check WordPress rewrite rules

A virtual ads.txt implementation generally depends on WordPress receiving:

/ads.txt

and identifying the request through its rewrite system.

If the endpoint returns 404 after enabling a virtual implementation, investigate:

  • permalink rules;
  • server rewrite configuration;
  • module activation;
  • physical-file conflicts;
  • WordPress root location.

Do not flush rewrite rules on every request

A plugin that adds a virtual endpoint may need to flush rewrite rules when the endpoint is first introduced.

It should not call:

flush_rewrite_rules()

on every page load.

That operation is comparatively expensive and unnecessary once rules are registered.

TheOneWP schedules its required rewrite refresh

The Ads.txt & App-ads.txt Editor uses dedicated rewrite rules for:

/ads.txt

/app-ads.txt

and handles the necessary rewrite refresh as an administrative lifecycle operation rather than continuously flushing rules on every request.

Step 13: check CDN caching

A CDN can continue serving an older ads.txt response after WordPress has already saved the new one.

The sequence can be:

WordPress updated
↓
origin response updated
↓
CDN still cached
↓
public ads.txt remains old

Inspect cache-related headers

Depending on the CDN, you may see headers such as:

Age:
X-Cache:
CF-Cache-Status:
Cache-Control:
ETag:
Last-Modified:

These headers can help identify whether the response is being served from cache.

Example

HTTP/2 200
content-type: text/plain
cf-cache-status: HIT
age: 2800

A:

HIT

or substantial:

Age

value can indicate that the edge is returning a cached copy.

Purge the specific ads.txt URL when possible

Instead of purging the entire website cache, invalidate:

https://example.com/ads.txt

when the CDN supports URL-specific purging.

Do not disable caching permanently without a reason

ads.txt is a small public resource that can generally be cached.

The problem is not caching itself.

The problem is:

serving stale content
after an intentional update

Check page-cache plugins too

A WordPress cache plugin may cache:

/ads.txt

even if no external CDN is involved.

After changing the file, test from:

  • a logged-out browser;
  • curl;
  • an external network;
  • a private browsing session.

Do not trust the logged-in administrator response alone

Many cache systems bypass cache for logged-in administrators.

You may see:

new ads.txt
as administrator

while anonymous crawlers receive:

old ads.txt
from cache

Test as an anonymous client

curl is useful because it does not carry your normal WordPress authentication cookies:

curl -sS \
    https://example.com/ads.txt

Step 14: compare CDN and origin when necessary

Advanced troubleshooting may require determining whether the stale response comes from:

  • WordPress;
  • the origin web server;
  • the CDN edge.

If you know the origin IP and direct origin access is supported, curl can temporarily resolve the production hostname to that IP:

curl \
    --resolve example.com:443:203.0.113.10 \
    https://example.com/ads.txt

This keeps the hostname:

example.com

while connecting to the selected IP.

Use origin testing carefully

This technique only works correctly when:

  • the origin accepts direct traffic;
  • the TLS certificate matches the hostname;
  • the virtual host is configured correctly;
  • the origin is not intentionally protected behind the CDN.

Do not weaken origin security simply to run this test.

Step 15: check security and maintenance layers

A security plugin, firewall or maintenance system can intercept:

/ads.txt

before the intended response is returned.

Possible outcomes include:

403 Forbidden

401 Unauthorized

503 Service Unavailable

CAPTCHA page

JavaScript challenge

maintenance HTML

ads.txt must remain publicly accessible

An advertising crawler cannot complete normal discovery if the endpoint requires:

  • WordPress login;
  • HTTP Basic Authentication;
  • a CAPTCHA;
  • a JavaScript challenge;
  • an allowlisted browser cookie.

Be careful with staging password protection

A staging environment can reasonably require authentication.

A production ads.txt endpoint intended for advertising discovery cannot rely on a crawler successfully passing that authentication barrier.

Do not apply site-wide challenges blindly

A WAF rule may challenge unfamiliar automated user agents.

If that same policy affects legitimate advertising crawlers, the ads.txt endpoint becomes inaccessible.

Step 16: verify case and filename exactly

The expected path is:

/ads.txt

Use lowercase.

Do not rely on:

/Ads.txt

/ADS.TXT

/ads.TXT

because URL and filesystem case behavior can vary across servers.

Do not accidentally publish ads.txt.txt

Some desktop systems hide known file extensions.

A file visually named:

ads.txt

may physically be:

ads.txt.txt

Verify the actual filename when uploading manually.

Step 17: check for a trailing slash redirect

The standard endpoint is:

/ads.txt

not:

/ads.txt/

If WordPress or another canonicalization rule redirects:

/ads.txt
↓
/ads.txt/

inspect why.

A text-file endpoint should generally retain its file-style URL.

Generic WordPress redirects can accidentally affect ads.txt

Redirect managers and canonicalization systems sometimes contain broad patterns such as:

everything without slash
→ add slash

or:

all missing URLs
→ homepage

Those rules can interfere with special root-level resources.

TheOneWP Redirect Manager addresses URL redirects as a separate layer and should be reviewed when debugging unexpected redirect behavior.

Check the complete redirect chain

A browser ending at:

/ads.txt

does not tell you whether the request took:

1 hop
or
8 hops

Use curl or another HTTP diagnostic tool.

Step 18: check HTTP status codes individually

Common responses mean different things.

200 OK

Resource successfully served.

This is the normal desired final response.

301 Moved Permanently

Permanent redirect.

Often appropriate for:

HTTP → HTTPS

or:

apex → www

302 Found

A temporary redirect.

It may be followed by crawlers where permitted by the ads.txt redirect rules, but permanent canonical changes are usually clearer with the appropriate permanent status.

307 Temporary Redirect

Another temporary redirect type recognized by the ads.txt specification.

401 Unauthorized

The resource requires authorization.

This is unsuitable for a normally public ads.txt deployment.

403 Forbidden

The server understands the request but refuses access.

Check:

  • WAF;
  • filesystem permissions;
  • security plugins;
  • server rules.

404 Not Found

No ads.txt resource is being served at the requested URL.

500 Internal Server Error

The server or WordPress failed while processing the request.

Inspect:

  • PHP errors;
  • plugin conflicts;
  • rewrite handlers;
  • server logs.

503 Service Unavailable

The resource is temporarily unavailable.

This may come from:

  • maintenance mode;
  • origin failure;
  • server overload;
  • CDN protection.

For a broader explanation of responses, see HTTP Status Codes for WordPress Sites, Explained.

Step 19: verify redirects do not terminate on the homepage

A common WordPress mistake is:

unknown URL
↓
301
↓
homepage

If:

/ads.txt

does not actually exist and gets redirected to:

/

the endpoint is not properly serving ads.txt.

The fact that the final request returns:

200

does not fix the missing resource.

Check final Content-Type after redirects

You may have:

/ads.txt
↓
301
↓
homepage
↓
200 text/html

which is clearly not equivalent to:

/ads.txt
↓
200 text/plain

Step 20: check that the live content matches the ad platform

For Google AdSense, compare the exact seller line provided by the account with the live ads.txt output.

Check:

  • advertising-system domain;
  • publisher ID;
  • DIRECT or RESELLER;
  • certification ID when supplied.

Publisher ID mismatches are common

For example:

AdSense account:
pub-1234567890123456

Live ads.txt:
pub-1234567890123457

The file is technically served correctly.

The account declaration is wrong.

Do not manually modify seller IDs unless the provider instructs you to

Advertising platforms provide the exact records expected for their systems.

Use those records rather than attempting to infer values from:

  • account names;
  • customer IDs;
  • analytics IDs;
  • website IDs;
  • ad-unit IDs.

Step 21: understand propagation delay

After fixing ads.txt, an advertising platform may not recognize the change immediately.

Google states that changes can take:

a few days

to appear in AdSense.

For low-traffic sites, Google notes that the process can sometimes take:

up to a month

because the file may be crawled less frequently.

Do not keep editing a correct file while waiting

If the live endpoint already returns:

correct URL
+
200 OK
+
text/plain
+
correct publisher record

repeatedly changing the file will not force immediate platform recognition and can complicate troubleshooting.

Separate serving status from crawler status

There are two different questions:

Question 1:
Is my server correctly
serving ads.txt?

Question 2:
Has the advertising platform
already recrawled it?

You can verify the first immediately.

You may need to wait for the second.

Use the Google ads.txt troubleshooter when relevant

Google provides an official ads.txt troubleshooting tool for publishers using AdSense.

It walks through checks including:

  • whether /ads.txt is reachable;
  • whether the publisher ID matches;
  • whether robots.txt blocks crawling;
  • whether domain redirects are correct;
  • whether HTTP and HTTPS versions are reachable.

Step 22: distinguish ads.txt from app-ads.txt

The two files use related syntax but serve different inventory environments.

ads.txt
→ website advertising inventory

app-ads.txt
→ app advertising inventory

They should not be confused merely because their line format is similar.

See ads.txt vs app-ads.txt: What’s the Difference?.

Do not rename app-ads.txt to ads.txt

If an advertising platform specifically requires:

app-ads.txt

publishing the same content only at:

/ads.txt

does not create the expected app resource.

Test app-ads.txt independently

When the site requires both, verify:

https://example.com/ads.txt

https://example.com/app-ads.txt

independently.

TheOneWP keeps the two resources separate

The Ads.txt & App-ads.txt Editor stores and serves ads.txt and app-ads.txt as independent resources.

This avoids treating one file as an alias of the other.

What happens when TheOneWP ads.txt content is empty?

The virtual endpoint should represent an intentionally configured resource rather than a meaningless blank response.

The current TheOneWP implementation treats an empty saved ads.txt value as not configured, allowing normal WordPress 404 handling rather than serving a blank virtual file.

Do not confuse an empty HTTP 200 file with a configured seller list

The ads.txt specification has specific handling for publishers that intentionally declare no authorized advertising systems.

Historically, completely empty files created ambiguity.

The current IAB specification defines a properly formatted placeholder mechanism for that special case.

If your intention is simply:

ads.txt has not been configured yet

a normal missing resource and an explicit no-authorized-sellers declaration are not conceptually the same thing.

Checking ads.txt from outside your network

Testing from your own office connection is useful.

An external crawler may encounter different infrastructure because of:

  • regional CDN edges;
  • firewall rules;
  • geographic restrictions;
  • IPv6 routing;
  • bot-management rules.

Use an external network when troubleshooting unexplained crawler failures

Possible tests include:

  • mobile data;
  • a remote server;
  • another geographic network;
  • a reputable HTTP diagnostic service.

The goal is to confirm the public endpoint behaves consistently outside your normal authenticated network.

Check IPv4 and IPv6 when the domain publishes both

If DNS contains both:

A
and
AAAA

records, different clients can reach different network paths.

A misconfigured IPv6 virtual host can create:

IPv4
→ 200 ads.txt

IPv6
→ 404

or another inconsistent result.

Force IPv4 with curl

curl -4 -i \
    https://example.com/ads.txt

Force IPv6 with curl

curl -6 -i \
    https://example.com/ads.txt

If IPv6 is advertised but the test fails, investigate the network or server configuration.

Check DNS after migrations

An ads.txt issue appearing immediately after a migration may have nothing to do with WordPress.

Possible causes include:

  • old DNS records;
  • mixed origin servers;
  • stale CDN configuration;
  • different www and apex destinations;
  • incomplete IPv6 migration.

Different origins can serve different ads.txt files

During migration, you might accidentally have:

Server A
→ new ads.txt

Server B
→ old ads.txt

If DNS or a load balancer sends requests to both, crawlers can receive inconsistent declarations.

Test repeatedly when load balancing is involved

Run:

curl -sS \
    https://example.com/ads.txt

several times and compare the output.

Inconsistent responses can reveal:

  • unsynchronized nodes;
  • multiple origins;
  • cache inconsistency.

Check server access logs

If you need to know whether crawlers are requesting:

/ads.txt

server or CDN access logs can provide evidence.

Look for:

request path
status code
user agent
timestamp
response size

Do not use access logs as proof that the content was valid

A log line such as:

GET /ads.txt 200

proves that a request received status 200.

It does not prove that the response contained:

correct publisher ID
+
valid syntax
+
text/plain

Check both request and response quality

Access log
→ did crawler reach it?

HTTP inspection
→ how was it served?

Content validation
→ what did it contain?

Check redirects through logs too

If a crawler requests:

/ads.txt

and receives:

301

the redirect access log can help reveal the next step.

See Reading a Redirect Access Log when redirect behavior needs deeper analysis.

Do not block ads.txt with maintenance mode

Some maintenance tools intercept nearly every frontend request.

That can transform:

/ads.txt

into:

503 maintenance page

or:

200 HTML maintenance page

during maintenance windows.

If continuous ads.txt availability matters, configure maintenance rules accordingly.

Do not password-protect the production endpoint

This is particularly common after staging-to-production migrations.

A leftover:

HTTP Basic Auth

configuration can make the entire site or endpoint return:

401 Unauthorized

to crawlers.

Do not redirect ads.txt to a login page

This response:

/ads.txt
↓
302
↓
/wp-login.php
↓
200 text/html

is not a valid public ads.txt deployment.

Do not add noindex and assume it matters

ads.txt is not a normal HTML document intended for search-engine indexing.

The important controls are:

  • public accessibility;
  • HTTP behavior;
  • crawler access;
  • correct content.

HTML SEO meta directives are not the mechanism used to manage this resource.

Do not add a canonical tag

A plain-text ads.txt resource does not need:

<link rel="canonical">

That would require inserting HTML into a plain-text protocol resource.

Do not include ads.txt in the XML sitemap

An XML sitemap exists to describe crawlable site URLs for search engines.

ads.txt has its own standard discovery location.

Adding:

/ads.txt

to your SEO XML sitemap is unnecessary.

TheOneWP XML Sitemap handles a completely different machine-readable resource.

Root-level machine-readable resources should remain independent

A WordPress installation can expose:

/robots.txt

/ads.txt

/app-ads.txt

sitemap URLs

but each follows a different specification and purpose.

TheOneWP Robots.txt Editor manages crawler instructions, while the Ads.txt & App-ads.txt Editor manages authorized advertising sellers.

A practical curl verification sequence

Start with the canonical HTTPS URL:

curl -i \
    https://example.com/ads.txt

Then check the root HTTP version:

curl -L -i \
    http://example.com/ads.txt

Then test www when relevant:

curl -L -i \
    https://www.example.com/ads.txt

Finally retrieve only the body:

curl -sS \
    https://example.com/ads.txt

A healthy result might look like

HTTP/2 200
content-type: text/plain; charset=UTF-8
cache-control: public, max-age=3600

google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0

The exact caching headers can vary.

The important core signals are:

successful response
+
plain text
+
valid content

Example: wrong Content-Type

HTTP/2 200
content-type: text/html

google.com, pub-1234567890123456, DIRECT

The body visually resembles ads.txt, but the MIME type does not match the ads.txt specification.

Example: soft 404

HTTP/2 200
content-type: text/html

<h1>Sorry, page not found</h1>

This is not a valid ads.txt response.

Example: stale physical file

WordPress editor:

google.com, pub-NEW, DIRECT


Public /ads.txt:

google.com, pub-OLD, DIRECT

Check:

  • physical file;
  • CDN cache;
  • page cache;
  • multiple origins.

Example: apex-domain problem

https://www.example.com/ads.txt
→ 200

https://example.com/ads.txt
→ 404

Configure the root domain so the ads.txt discovery path reaches the intended resource.

Example: HTTP problem

https://example.com/ads.txt
→ 200

http://example.com/ads.txt
→ 404

Google recommends making both protocols reachable, normally by redirecting HTTP to the working HTTPS URL.

Example: robots.txt problem

User-agent: *
Disallow: /ads

Review the directive because it can prevent crawlers that respect robots.txt from retrieving the ads.txt path.

Example: security challenge

HTTP/2 403

Checking your browser...

The firewall or bot-management configuration is interfering with public crawler access.

Example: redirect to homepage

/ads.txt
↓
301
↓
/
↓
200 text/html

This does not constitute a working ads.txt resource.

Example: correct server, wrong seller data

HTTP/2 200
Content-Type: text/plain

google.com, pub-WRONG, DIRECT

HTTP delivery is healthy.

Advertising configuration is not.

WordPress troubleshooting order

When ads.txt is not working on WordPress, use this sequence:

1. Open /ads.txt

2. Check HTTP status

3. Check Content-Type

4. Check response body

5. Check apex and www

6. Check HTTP and HTTPS

7. Check robots.txt

8. Check redirects

9. Check physical ads.txt

10. Check WordPress virtual endpoint

11. Check page cache

12. Check CDN cache

13. Check firewall / bot rules

14. Compare seller ID

15. Wait for recrawl

Do not start by reinstalling WordPress

An ads.txt delivery problem is normally much narrower than a broken WordPress installation.

Identify the failing layer first.

Do not start by flushing every cache repeatedly

Check whether the public response is actually stale.

If the wrong content comes directly from the origin, repeatedly purging the CDN will not repair the source.

Do not keep changing seller records during troubleshooting

Separate:

transport debugging
from
content editing

First make sure one known test version is served consistently.

Then validate the actual seller declarations.

Do not create multiple competing ads.txt implementations

If one plugin does not appear to work, installing three more ads.txt plugins can create:

  • rewrite conflicts;
  • unclear ownership;
  • stale options;
  • different output depending on request order.

Use one source of truth.

Do not forget hosting-level ads.txt systems

Some advertising platforms, hosting systems or managed-site products can inject ads.txt outside WordPress.

If WordPress output does not match your settings, investigate the complete hosting stack.

Do not assume the file is correct because AdSense stopped showing an alert

An advertising platform’s status can lag behind the live endpoint.

Your own HTTP verification should remain independently reproducible.

Do not assume the file is wrong because AdSense still shows an alert immediately after a fix

Crawler recognition is not instantaneous.

Once the server response is demonstrably correct, allow time for recrawling.

How TheOneWP simplifies ads.txt delivery

TheOneWP Ads.txt & App-ads.txt Editor provides separate editors for:

ads.txt

app-ads.txt

and publishes configured content through the standard root-level URLs.

Virtual delivery avoids manual FTP editing

Instead of maintaining:

/public_html/ads.txt

manually, the configured text can be stored inside WordPress and served through the virtual endpoint.

Physical files still take precedence at the web-server layer

If a real:

ads.txt

exists in the public WordPress root, the server can return it before WordPress receives the request.

That is why checking for a physical file is part of the module workflow.

Saved output should always be verified publicly

The administration screen is only the configuration layer.

The authoritative verification target is:

https://your-domain.example/ads.txt

because that is what advertising crawlers see.

Use the same principle for app-ads.txt

If app inventory is relevant, verify:

https://your-domain.example/app-ads.txt

independently instead of assuming that a working ads.txt endpoint proves the app file works too.

Complete ads.txt verification checklist

  • Open /ads.txt on the root domain.
  • Confirm the final resource returns a successful HTTP response.
  • Prefer a final 200 OK response.
  • Verify Content-Type: text/plain.
  • Confirm the response body contains plain text rather than HTML.
  • Check that the root domain can discover the resource.
  • Test the apex domain.
  • Test the www hostname when used.
  • Test HTTP.
  • Test HTTPS.
  • Follow and inspect the redirect chain.
  • Avoid unnecessary redirect hops.
  • Check that redirects stay within permitted ads.txt rules.
  • Verify that the final destination still ends in valid ads.txt content.
  • Check robots.txt for rules that block the path.
  • Check crawler-specific robots.txt directives.
  • Verify TLS certificate validity.
  • Check for HTTP Basic Authentication.
  • Check firewall and bot-management challenges.
  • Check maintenance mode.
  • Check for a physical ads.txt file.
  • Check for competing WordPress ads.txt plugins.
  • Check WordPress rewrite behavior.
  • Check for trailing-slash redirects.
  • Check global canonical redirects.
  • Check page-cache output.
  • Check CDN cache status.
  • Purge stale ads.txt cache after updates when required.
  • Compare origin and CDN responses when necessary.
  • Check IPv4 and IPv6 where both are published.
  • Check multiple origin nodes after migrations.
  • Verify the advertising-system domain in every seller record.
  • Verify every publisher or seller account ID.
  • Verify DIRECT vs RESELLER.
  • Check optional certification IDs when supplied.
  • Check supported variable declarations separately.
  • Remove accidental rich-text formatting.
  • Remove invalid characters.
  • Review duplicate records.
  • Investigate conflicting records.
  • Compare the live file with the advertising platform’s required line.
  • Verify ads.txt and app-ads.txt independently.
  • Check access logs when crawler activity needs investigation.
  • Allow time for advertising platforms to recrawl a corrected file.

Related guides

Final recommendation

The fastest way to verify ads.txt is to stop treating the browser view as the complete test.

Check the endpoint as an HTTP resource:

URL
→ /ads.txt

status
→ 200 OK preferred

Content-Type
→ text/plain

body
→ valid ads.txt records

root-domain discovery
→ works

HTTP / HTTPS
→ works

robots.txt
→ does not block it

redirects
→ valid

seller data
→ matches ad platform

Start with:

curl -i \
    https://example.com/ads.txt

Then test:

http://example.com/ads.txt

https://www.example.com/ads.txt

when those variants exist.

If the response is wrong, identify which layer owns the failure:

404
→ endpoint or rewrite problem

HTML response
→ wrong handler or soft 404

old content
→ physical file or cache

403 / challenge
→ security layer

wrong redirect
→ canonicalization problem

correct delivery but wrong ID
→ ads.txt content problem

On WordPress, also verify whether a physical file is overriding a virtual endpoint. A plugin can save the correct content perfectly while the web server continues serving an older physical ads.txt before WordPress is ever involved.

TheOneWP Ads.txt & App-ads.txt Editor provides a virtual WordPress-managed endpoint for both advertising files and explicitly separates their configuration. After every significant change, the final verification should still happen against the public URL rather than only inside wp-admin.

Once the live resource returns the correct plain-text content with a healthy HTTP response, correct root-domain behavior and valid seller IDs, the server-side implementation is working. If an advertising platform still reports an issue immediately afterward, distinguish a crawler-refresh delay from an actual delivery error before changing the file again.

Simplify your WordPress stack

A modular WordPress toolkit. 104 focused tools.

Ultimately, you can build cleaner workflows, maintain fewer plugins and enable only the features each website actually needs.