ECS Decision Snapshot
{{ verdict.label }}
{{ verdict.subline }}
{{ verdict.badgeText }} {{ resolverCapability.badgeText }} {{ params.type }} {{ params.domain }} Requested ECS: {{ requestedEcsLabel }} Response scope: {{ scopeAssessment.shortLabel }} Changed answers: {{ diff.changed }} TTL drift: {{ diff.ttlOnly }}
{{ resolverCapability.title }} {{ resolverCapability.note }}
{{ stageText }}
{{ timeout_ms }} ms
Attribution reading

{{ interpretationLead }}

Recommended next checks
  1. {{ step }}
Operational facts
  • {{ fact }}
Evidence boundaries
What this run supports
  • {{ item }}
What it does not prove
  • {{ item }}
Answer ECS seen ECS TTL No-ECS seen No-ECS TTL Interpretation Copy
{{ row.answer }} {{ row.ecsSeenLabel }} {{ row.ecsTtl }} {{ row.plainSeenLabel }} {{ row.plainTtl }} {{ row.deltaLabel }}
No answer records were returned for this comparison.
Resolver Capability ECS echo Changed TTL Overlap Verdict Copy
{{ row.resolver }}
{{ row.statusLabel }} ยท {{ row.latencyLabel }}
{{ row.capabilityText }}
{{ row.echoScope }}
{{ row.scopeNote }}
{{ row.changed }} {{ row.ttlOnly }} {{ row.overlapLabel }} {{ row.verdict.badgeText }}
{{ row.note }}
No resolver matrix data.
Scope interpretation

{{ scopeAssessment.longText }}

Scope highlights
  • {{ item }}
Resolver guardrails
  • {{ item }}
Scope ledger
Pair Requested ECS Echo scope Scope verdict Status
{{ row.pairLabel }} {{ row.requestedEcs }} {{ row.echoScope }} {{ row.scopeVerdict }} {{ row.statusLabel }}
Radar legend
  • Answer drift shows how much the returned answer membership changed between the ECS and control runs.
  • TTL drift shows cache-shape changes where the answers stayed present but the lifetimes moved.
  • Latency swing is the absolute DoH response-time gap between the two runs.
  • Scope proof rises when the resolver both accepts the hint and returns an interpretable response scope.
  • Resolver trust reflects whether the resolver is a credible ECS path or a deliberate baseline/control.

      
:

Introduction

EDNS Client Subnet, usually shortened to ECS, lets a recursive DNS resolver send a shortened client network hint upstream when it asks for a DNS answer. Content delivery networks and other location-sensitive services can use that hint to choose an address that fits the user's region without learning the user's full IP address.

That matters because one hostname can behave in several distinct ways under ECS. It may return different A or AAAA records for different networks, it may return the same records but mark them reusable for a broader or narrower cache scope, or it may ignore the hint completely. Those differences affect both what a resolver caches and how confidently you can explain a routing result.

A useful ECS check therefore needs more than a simple before-and-after lookup. It needs one query with a subnet hint, one control query without that hint, and a resolver path that can make the cache scope visible when ECS is accepted. Reading all three together helps separate genuine answer steering from ordinary cache churn.

The limit is just as important as the signal. DNS evidence is not the same thing as end-to-end application evidence. A changed answer set can still map to healthy equivalents, and an unchanged answer set can still hide different caching rules or resolver policy.

Requested subnet 203.0.113.0/24 or 2001:db8::/56 ECS-capable resolver Hint sent upstream Control resolver path No ECS hint upstream Compared evidence Changed answers TTL drift and status Echoed scope Resolver-specific signal
A good ECS read compares a hinted lookup, a no-hint control, and the resolver path itself. Useful evidence includes answer movement, returned scope, and whether the same pattern appears outside a control baseline.

Technical Details

RFC 7871 separates two closely related ideas: the source prefix and the scope prefix. The source prefix is the shortened client network carried in the ECS option. The scope prefix in the response tells caches how broadly that answer can be reused. Matching address family, address, and source prefix matter because recursive resolvers use those fields to decide whether a response is a valid ECS response at all.

Caching behavior depends on that scope. If the returned scope is broader than the requested subnet, the answer can be reused for a wider slice of clients. If the returned scope is narrower, the upstream path kept the answer more tightly bound to that network. A global /0 scope means the answer is effectively cacheable for everyone in that address family, which is common for negative responses and for records that do not vary by client location. Google's ECS guidance also warns against overlapping scopes because cached results can then depend on query order rather than policy alone.

The comparison here uses two DNS-over-HTTPS lookups on the same resolver path: one with an ECS token and one without it. For address lookups, the returned answer membership, TTL values, DNS status, elapsed time, and any echoed scope are normalized and compared side by side. Non-address record types are still checked, but they stay plain resolver comparisons because no client-subnet hint is attached to those runs.

The resolver lens changes what the outcome can prove. Google Public DNS accepts edns_client_subnet in its DoH JSON API and returns an echoed scope field, so it can serve as the positive attribution path. Cloudflare 1.1.1.1 is useful as a control because its privacy-focused public resolver does not send ECS to authoritative servers for ordinary production lookups. Taken together, those resolver paths show whether answers move under ECS and whether the same hostname stays flat on a control baseline.

U = unique answers across ECS and control responses A = changed answersU×100 T = TTL-only differencesU×100 L = min(|Δms|150×100,100) Signal = round(clamp((0.5A+0.2T+0.1L)×trustFactor×0.75+0.15scopeProof+0.10resolverTrust,0,100))

The 0 to 100 score above is a triage score used by this checker, not an Internet standard. It gives the most weight to answer membership change, then TTL-only drift, then latency swing, while scope proof and resolver trust keep the score from treating a control path as positive ECS evidence. That is why the same answer change reads differently on Google than it does on the Cloudflare baseline.

How to read requested versus echoed scope
Scope reading Technical meaning Practical consequence
Echoed scope matches the requested subnet The resolver accepted the family and prefix you asked it to test. That is the cleanest attribution trail when the answer set also changes.
Echoed scope is broader than requested The returned answer is cacheable for a wider network than the original hint. Broad reuse can flatten differences that you expected to see at a smaller boundary.
Echoed scope is narrower than requested The upstream path kept the answer more tightly scoped than the request alone implied. Repeat nearby prefixes before you generalize the result to a larger region.
No echoed scope on an ECS-capable resolver The request completed, but scope evidence is weak or missing. Treat answer changes cautiously and re-test with another subnet or hostname.
Baseline resolver path The resolver is acting as a privacy-first control rather than a positive ECS source. Differences there are useful context, but not clean proof of ECS steering.

The requests do not stay local. Each run sends the selected hostname, record type, and optional ECS token to the chosen public resolver over DoH. If you use the current-address helper, the page also queries a public IP service, then truncates that address locally to a network base before building the token.

Everyday Use & Decision Guide

For a first pass, keep the question narrow. Use an A or AAAA lookup, choose Google when you need positive ECS attribution, and keep the peer comparison enabled when you want to know whether the same hostname also looks steady on a control path. If you do not already know which network to test, the current-address helper gives you a practical /24 or /56 starting point instead of a full host address.

  • Open Runbook Brief first when you want the short reading, recommended next checks, and evidence boundaries in one place.
  • Use Answer Ledger when you need exact ECS-only answers, control-only answers, or TTL-only drift rows.
  • Use Resolver Signal Matrix when you need to see whether Google and Cloudflare tell the same story under the same inputs.
  • Use Scope Notes when the echoed subnet matters as much as the answer list.
  • Use Resolver Evidence Radar when you need a compact exportable summary of answer drift, TTL drift, latency swing, scope proof, and resolver trust.

The most common overread is treating any movement as proof of steering. Changed answers is the strong signal. TTL drift without answer change usually means cache state moved while the destination list stayed put. A missing echoed scope on Cloudflare is normal for the control path, but the same outcome on Google weakens attribution and deserves a second pass.

If the question is really about MX, TXT, NS, or another non-address record, use the page as a resolver comparison rather than an ECS proof check. The result can still show status differences or answer drift, but it cannot tell you how a client-subnet hint would have changed the lookup because no hint was sent. Before you trust a dramatic summary badge, line up Changed answers, Response scope, and the peer row in Resolver Signal Matrix and make sure they support the same story.

Step-by-Step Guide

  1. Enter the hostname or domain you want to inspect. If you paste a URL, the page reduces it to the host before the lookup runs.
  2. Choose the record type. Use A or AAAA when the goal is to test ECS-driven steering. Use another type only when you want a plain resolver comparison.
  3. Pick the resolver lens and probe depth. Google is the positive ECS path, while Cloudflare is the privacy baseline. Cross mode adds the peer resolver row automatically.
  4. Enter a client subnet or use the current-address helper. Keep the prefix aligned to the network you actually want to simulate, not a random host inside it.
  5. Run the check and read the ECS Decision Snapshot and Runbook Brief before drilling into individual rows.
  6. Open Answer Ledger, Resolver Signal Matrix, Scope Notes, Resolver Evidence Radar, and JSON only as far as the question needs, then export CSV, DOCX, chart files, or JSON if you need to share the evidence.

Interpreting Results

Status changes come first. If the ECS and control lookups return different DNS status codes, that outranks TTL movement because the class of answer itself changed. After that, answer membership change is the clearest sign that the hostname reacted to the client-network hint.

How to interpret the main result patterns
Observed pattern What it usually means What to check next
Status pair differs The resolver did not treat the ECS and control queries as the same class of answer. Validate with a second resolver and, if possible, authoritative or CDN-side logs.
Changed answers > 0 The answer membership changed between the ECS and control runs. Confirm that the returned subnet belongs to a real steering boundary you expected to test.
Changed answers = 0 and TTL drift > 0 The destination list stayed aligned while cache lifetime moved. Re-run later before you treat it as routing drift.
Changed answers = 0, TTL drift = 0, readable scope The resolver accepted the hint, but the tested hostname still produced the same content. Try a different subnet or hostname if you expected a stronger geographic split.
Response scope = No echoed scope on Google The attribution trail is weak even if the request completed. Retest with another prefix, another hostname, or an authoritative configuration check.
Signal score >= 70 The combined evidence is strong. Still read the underlying rows, because the score is a summary, not proof of traffic landing.

The peer resolver row is the fastest sanity check when the first result looks dramatic. If Google shows answer drift while Cloudflare stays flat, you are likely looking at a resolver path that reacts to ECS while the privacy baseline does not. If both rows move, the hostname itself is more likely to be steering by network. In either case, the DNS result is still only the DNS result. Application health, edge selection, and request landing need their own verification.

Worked Examples

A CDN region split shows up clearly

You test an A record with a subnet that should land in a different region. The Google primary row reports Changed answers = 2, overlap drops sharply, and the echoed scope matches the requested /24. The Cloudflare peer row stays steady. That is strong evidence that the hostname reacts to the network hint rather than simply returning stale cache on both resolvers.

The answers stay the same but the cache shape moves

A rerun shows Changed answers = 0, TTL drift = 3, and 100% overlap. The summary badge may still look interesting, but the safer reading is cache churn, not destination change. Wait for the TTL window to move again or repeat the same lookup before you open a routing incident.

Weak attribution needs a cleaner test

You probe Google with an address record and a subnet, but Scope Notes says No echoed scope and the answer list stays flat. That does not prove the hostname ignores ECS. It tells you the evidence is weak. Try a nearby prefix, a hostname closer to the CDN edge policy, or an authoritative ECS validation pass before you draw a hard conclusion.

FAQ

Why does the summary say Record-type comparison only?

Only A and AAAA runs attach a client-subnet hint here. If you choose MX, TXT, NS, or another type, the page still compares resolver answers, but it is no longer an ECS steering test.

Why does Cloudflare usually look like a baseline instead of positive ECS evidence?

Cloudflare 1.1.1.1 is used as a privacy-first control path. Its public resolver does not send the ECS header to authoritative servers for normal production lookups, so it is helpful for comparison but not for positive ECS attribution.

What does a broader or narrower echoed scope actually mean?

A broader echoed scope means the returned answer can be reused for a wider network than you requested. A narrower scope means the upstream path kept the answer tied to a smaller network. Both change how caches may reuse the result, even when the answer text itself stays the same.

Why do both sides look identical even after I enter a subnet?

That can happen for several ordinary reasons: the hostname may not vary by client network, the chosen subnet may not cross a steering boundary, the resolver path may be a control baseline, or the record type may not support ECS in this page. Check the record type first, then the resolver lens, then the echoed scope.

What happens when I click Use my IP?

The page asks a public IP service for your current outward-facing address, then trims it locally to a network base before building the ECS token. The default is /24 for IPv4 and /56 for IPv6.

Does a high signal score prove users reached a different server?

No. It proves that the DNS evidence was strong under the tested conditions. You still need application telemetry, CDN logs, or end-to-end probing if the real question is where traffic actually landed.

Glossary

ECS
EDNS Client Subnet, a DNS extension that carries a shortened client network hint with a query.
Source prefix
The network prefix placed in the ECS request, such as 203.0.113.0/24.
Scope prefix
The cache-reuse boundary returned in an ECS response.
DoH
DNS over HTTPS, the transport used for the live resolver queries in this page.
TTL
Time to live, the remaining cache lifetime attached to a returned DNS record.
Overlap
The share of unique answers that stay present on both the ECS and no-ECS sides of the comparison.