For eight years, Safari’s tracking prevention followed one rule: the request may leave, but it travels light. No third-party cookie, a shortened first-party cookie, a trimmed referrer. The pixel still fired, and something on the other end still received a hit.

Safari 27 breaks that rule. For a list of domains chosen by Apple, the request is refused before it reaches the network. No hit, no log line on the vendor side, nothing to model from.

Most of what has been written about this since late September comes from one trade press story and a lot of retelling. I wanted the mechanism, so I did three things: I read the WebKit commits that implement the block, I read the public bug in which The Trade Desk asked Apple to lift it, and I reproduced the behaviour on Safari 27.2 with a test page. This article is the result. Where I am relaying someone else’s finding without having verified it, I say so.

The short version

From “starve the cookie” to “refuse the request”

It helps to recall what Safari did before, because the audit reflexes most of us have were built for that world. WebKit’s own Tracking Prevention reference describes the earlier layers:

Layer What it does Does the request leave?
Third-party cookie blocking “ITP by default blocks all third-party cookies. There are no exceptions to this blocking.” Yes, without cookies
7-day cap on script-written storage Cookies created in JavaScript and other script-writable storage are deleted after 7 days without user interaction Yes
24-hour cap with link decoration When a link carries tracking decoration, JavaScript cookies on the landing page are capped at 24 hours Yes
CNAME and IP cloaking defence Cookies set in an HTTP response are capped at 7 days when a “first-party” subdomain resolves to a third party Yes
Safari 27 tracking policy block Cross-site requests to listed domains are refused No

Every earlier layer degraded the data. This one removes it. That difference matters for diagnosis: a degraded signal leaves a trace you can compare against, an absent one leaves a hole that looks like lower traffic.

If you want the full map of what a browser can and cannot expose once cookies are gone, I covered it in Beyond Cookies: The Complete Map of Browser Tracking Signals.

What the WebKit source actually says

WebKit is open source, so the mechanism is public even if the list is not. Six commits tell the story.

Date Commit What it does
Feb 12, 2026 307413@main Separates tracker domains that may be blocked only with advanced protections from those that may be blocked by default
Feb 13, 2026 307525@main (PR 58670) “Unconditionally block requests going to certain domains”: 11 lines, the list itself lives in a file Apple does not publish
Feb 18, 2026 307774@main “Remove advanced privacy protection condition for blockable requests”: the block now applies outside Private Browsing
Jul 2, 2026 bug 318165 Simplifies the rule to “block any non-main-frame subresource whose destination is a targeted domain” and removes the latch that let the first request through
Sep 25, 2026 bug 324589 Replaces the static domain list with a content rule list provided by the WebPrivacy framework, reloaded when it is updated
Oct 8, 2026 323137@main Removes the last references to the private list file, which is “not needed” any more

The February commit is the one everyone quotes. Here is the part that matters, from Source/WebKit/Platform/cocoa/WebPrivacyHelpers.mm:

#if !defined(IS_REQUEST_UNCONDITIONALLY_BLOCKABLE)
#define IS_REQUEST_UNCONDITIONALLY_BLOCKABLE(domain) false
#endif

// inside isRequestBlockable()
auto domain = WebCore::RegistrableDomain { URL { makeString("http://"_s, request.url().host()) } };
if (IS_REQUEST_UNCONDITIONALLY_BLOCKABLE(domain))
    return true;

Two things to read here. First, the macro returns false in the public repository: the real list only existed in Apple’s internal build. Second, the check works on the registrable domain, the eTLD+1. Listing adsrvr.org blocks match.adsrvr.org, insight.adsrvr.org and every other subdomain in one stroke.

The four conditions of a block

The September 25 commit rewrote the decision in NetworkLoadChecker::shouldBlockForTrackingPolicy. Stripped of plumbing, it reads like this:

if (parameters.isMainFrameNavigation)
    return false;                                   // 1. navigations are never blocked

if (!networkSession->isTrackingPreventionEnabled())
    return false;                                   // 2. tracking prevention must be on

if (RegistrableDomain(request.url()).matches(topOrigin->data()))
    return false;                                   // 3. same-site requests are exempt

if (!backend->shouldBlockLoad({ request.url(), m_mainDocumentURL, m_frameURL, resourceType, false, requestMethod }))
    return false;                                   // 4. the URL must match the rule list

return true;                                        // blocked by tracking protections
HOW SAFARI 27 DECIDES TO BLOCK A REQUEST
Page issues a network request
↓
1. Main-frame navigation?
a click, a redirect, a page load
→ yes: allowed
↓ no
2. Tracking prevention on?
the "Prevent cross-site tracking" setting
→ no: allowed
↓ yes
3. Same site as the page?
same registrable domain (eTLD+1)
→ yes, first-party: allowed
↓ no, cross-site
4. Matches the WebPrivacy rule list?
pushed by Apple, reloaded on update, no OS release needed
→ no: allowed
↓ yes
BLOCKED
the request never leaves the browser
Source: NetworkLoadChecker::shouldBlockForTrackingPolicy, WebKit, September 25, 2026.

Apple’s own test suite confirms each branch. The test file ScriptTrackingPrivacyTests.mm contains four tests whose names are a specification in themselves: SameSiteFetchNotBlocked, MainFrameNavigationNotBlocked, CrossSiteFetchBlocked and CrossSiteFetchNotBlockedWhenResourceLoadStatisticsDisabled.

Those tests use a fixture domain called tainted.example. That detail explains an oddity: the production list reported in September contained a tainted.example entry. It is Apple’s test domain, shipped along with the real ones.

The list became remote-controlled on September 25

This is the change I have not seen discussed, and it is the most important one for anyone planning ahead. The commit message says:

This patch replaces the static domain list in the network process with a content rule list that WebPrivacy provides. […] It caches the list, sends it to the network process, and reloads it when WebPrivacy posts an update.

Before that commit, changing the list meant changing a file and shipping a build. After it, the list is data. It also changed format: a content rule list can match URL patterns, resource types and request methods, not only a domain name. Apple can be more surgical than a whole-domain block, or broader.

The preference that gates the whole feature is named ScriptTrackingPrivacyNetworkRequestBlockingEnabled, described in the source as “Block network requests to known tracking domains”, with a default value of true.

Who was on the list: the Trade Desk ticket

The list is private, but one version of it is public because a vendor wrote it down. On September 21, 2026, Ian Meyers, senior director of engineering at The Trade Desk, filed WebKit bug 324771, priority P1, against Safari 27 on iOS 27. He listed nine entries:

Domain Owner Role
uidapi.com Unified ID 2.0 Identity
adsrvr.org The Trade Desk Ad requests and delivery
id5-sync.com, eu-1-id5-sync.com ID5 Identity
rlcdn.com, pippio.com LiveRamp Identity
permutive.com Permutive Audience data
ad.gt Audigent Audience data
tainted.example Apple Test fixture

His argument was that the list targets “post-cookie” identity, and that adsrvr.org does not belong on it because it is the company’s core ad request and delivery domain. The practical effect, as AdExchanger reported on September 29, was that The Trade Desk could not serve ads in Safari on iOS 27, which had shipped on September 14. Their test on a Yahoo article showed The Trade Desk’s bids blocked while bids through ad.doubleclick.net went out normally.

The ticket then moved quickly. John Wilander, who leads privacy work on WebKit, acknowledged it the next day, pointed to an iOS 27.2 beta on October 5, and marked the bug resolved on October 9. Note what the resolution covers: the ticket is about one domain. It says nothing about the eight others.

What I measured on Safari 27.2

Reading code tells you what can happen. I wanted to see what does happen, so I built a small test page. It is served locally, opened in Safari in a normal window with default settings, and it calls a list of hosts with a cross-site fetch in no-cors mode. A blocked request rejects; a request that leaves resolves, whatever the server answers. To rule out a network problem, I called the same hosts from the command line outside the browser.

The machine runs macOS 27.2 with Safari 27.2, which is the beta line that carries the Trade Desk fix.

Host Safari 27.2 Time Outside the browser
prod.uidapi.com Load failed 5 ms Responds
id5-sync.com Load failed 0 ms Responds
eu-1-id5-sync.com Load failed 1 ms No response (control inconclusive)
idsync.rlcdn.com Load failed 0 ms Responds
pippio.com Load failed 3 ms Responds
cdn.permutive.com Load failed 1 ms Responds
a.ad.gt Load failed 0 ms Responds
match.adsrvr.org Sent 294 ms Responds
insight.adsrvr.org Sent 50 ms Responds
ad.doubleclick.net Sent 310 ms Responds
www.google-analytics.com Sent 482 ms Responds
connect.facebook.net Sent 570 ms Responds
bat.bing.com Sent 474 ms Responds
snap.licdn.com Sent 698 ms Responds
static.criteo.net Sent 344 ms Responds
SAFARI 27.2: WHICH THIRD-PARTY CALLS LEAVE THE BROWSER
Publisher or advertiser page in Safari 27.2
↓ third-party call
WebKit tracking policy check
BLOCKED in 0 to 5 ms: identity and data vendors
Unified ID 2.0
uidapi.com
ID5
id5-sync.com, eu-1-id5-sync.com
LiveRamp
rlcdn.com, pippio.com
Permutive
permutive.com
Audigent
ad.gt
REQUEST SENT: ad delivery and measurement
The Trade Desk
adsrvr.org (unblocked in 27.2)
Google
doubleclick.net, google-analytics.com
Meta
connect.facebook.net
Microsoft
bat.bing.com
LinkedIn
snap.licdn.com
Criteo
static.criteo.net
Measured on October 13, 2026, Safari 27.2 on macOS 27.2, normal browsing, default settings.

Three readings.

The timing is the signature. A request that fails in 0 to 5 milliseconds did not fail on the network. No DNS lookup, no TLS handshake completes that fast. The browser refused it locally. A request that leaves takes tens to hundreds of milliseconds.

The identity vendors are still blocked. Seven of the eight real entries from the September list fail on 27.2. The fix released The Trade Desk’s ad domain and, as far as this test shows, nothing else.

The mainstream pixels are untouched by this mechanism. Google Analytics, Google’s ad domain, the Meta pixel loader, Microsoft UET, the LinkedIn Insight Tag loader and Criteo all sent their request. If your Safari conversions dropped in September and you only run those tags, this block is not your cause.

The limits of this test are real and you should weigh them: one device, macOS rather than iOS, a beta build, a page served from 127.0.0.1. I did not test Private Browsing, in-app web views, or other iOS browsers.

What it breaks, and for whom

The headline “Apple blocks ad tech” hides the fact that the damage is very unevenly distributed.

Publishers

This is where it hurts today. Identity modules in a header bidding setup call exactly the hosts in the table above. When id5-sync.com or rlcdn.com is refused, the user ID module returns nothing and the bid request leaves without that identifier. The auction still runs. What changes is the price buyers are willing to pay for an impression they cannot recognise. Expect the effect in Safari yield, not in fill.

Audience platforms are hit the same way. If Permutive’s domain is refused, segments are not computed in that session and audience-targeted line items lose that inventory. If you run Google Ad Manager and want the wider picture of where those signals plug in, see Google Ad Manager: The Complete Publisher’s Guide.

Advertisers

For an advertiser running Google, Meta, Microsoft and LinkedIn tags, this mechanism changes nothing measurable today. The exposure is indirect: programmatic campaigns that rely on UID2, RampID or ID5 for frequency capping and audience matching lose reach on Safari, and conversion paths that involved those identifiers get shorter.

During the two to three weeks when adsrvr.org was listed, advertisers buying through The Trade Desk lost Safari on iOS 27 as inventory entirely. If you see a hole in that channel between mid-September and early October, restricted to Safari on iOS 27, you now know its name.

Analysts

The trap is misattribution. A Safari-only dip in September invites the usual suspects: consent rate, a release, seasonality. Add one line to the checklist: was a blocked vendor part of the path? And keep the reverse in mind too, since most Safari anomalies this autumn will have nothing to do with this list.

How much traffic is concerned

Statcounter put Safari at 18.27% of browser usage worldwide in September 2026. That figure understates the surface for this change, because on iOS outside the European Union every browser is built on WebKit. Whether Chrome or Firefox on iOS apply the same block is a question I have not tested; the code path is in WebKit, the preference that enables it is set per application.

How to audit your own site in ten minutes

You do not need to trust any list, including mine. You can ask the browser.

Step 1: collect the hosts your pages call

Open your site in Chrome with DevTools, record a session that covers a product page, a cart and a confirmation, and export the HAR. Extract the distinct third-party hosts. Add the hosts your tag manager, your consent platform and your header bidding wrapper can call but did not call in that session.

Step 2: test them in Safari 27

Open a blank local page in Safari 27, not your own site, so that every host is cross-site and your Content Security Policy does not interfere. Then run this in the Web Inspector console:

const hosts = [
  'id5-sync.com',
  'ad.doubleclick.net',
  // paste your hosts here
];

const rows = [];
for (const host of hosts) {
  const start = performance.now();
  let result = 'sent';
  try {
    await fetch('https://' + host + '/?t=' + Date.now(), { mode: 'no-cors', cache: 'no-store' });
  } catch (error) {
    result = 'failed';
  }
  rows.push({ host, result, ms: Math.round(performance.now() - start) });
}
console.table(rows);

Step 3: read the result

What you see What it means Next move
Sent The request left the browser Nothing to do for this mechanism
Failed in under 10 ms Refused locally Run the control in step 4
Failed after several seconds Network timeout, DNS filter or dead host Not this mechanism

Step 4: run the control

A fast failure can also come from a content blocker extension or from a DNS filter that answers instantly. Rule those out: disable Safari extensions for the test, and call the same host from a terminal with curl -s -o /dev/null -w '%{http_code}' https://host/. If the terminal gets an HTTP status and Safari fails in a few milliseconds, the browser is the one refusing.

Step 5: confirm in your reports

Segment the affected metric by browser and by operating system version. The signature of this block is narrow: Safari on iOS 27 or macOS 27, starting on the day your users upgraded, with other browsers flat. Reconcile against a system that does not depend on the browser, such as orders in your back office. I described that reconciliation in Why GA4, SFCC and Offline Orders Will Never Match.

Repeat the test after each Safari update. The list is data now, so the answer has an expiry date.

What still fires

Go back to the four conditions. Two of them are exemptions written into the code, and they define what survives.

Same-site requests are exempt. Condition 3 compares the registrable domain of the request with the registrable domain of the page. A request from www.shop.example to collect.shop.example, or to www.shop.example/collect, is never evaluated against the list. This is not a loophole someone found. It is a branch in the function and a named test in Apple’s suite.

Main-frame navigations are exempt. A click that takes the user through a redirect domain is a navigation, not a subresource. Click trackers that work by redirect are outside this mechanism. They remain subject to link tracking protections, which are a different layer.

Server-to-server calls never meet the browser. A conversion sent from your server to a vendor API is invisible to WebKit by construction.

TWO PATHS TO A VENDOR: THE ONE SAFARI CAN CUT AND THE ONE IT CANNOT SEE
Browser: Safari 27 on shop.example
PATH 1: client-side
WebKit tracking policy check
↓ cross-site request: blocked
Listed vendor domain
never receives the hit
PATH 2: server-side
First-party collection endpoint
shop.example/collect
↓ same-site request: exempt, then event forwarded
Tagging server
sGTM or custom, your infrastructure
↓ server-to-server, outside the browser
Vendor server API
Consent still applies: forward only what the user agreed to.

Put together, the architecture that survives is the one many teams have already been moving to: a first-party collection endpoint on your own domain, a tagging server behind it, and vendor APIs called from that server. I described the moving parts in Server-Side Tracking Demystified and the infrastructure choices in Server-Side Tracking Architecture: Reverse Proxy, DNS Cloaking and First-Party Resilience. For the vendor side, see the Meta Conversions API guide and Enhanced Conversions vs Customer Match.

What does not fix it

Renaming the domain. A vendor can move to a new domain, and Apple can add it to a list that no longer requires a release. This is a race the vendor loses by design.

Assuming a first-party subdomain is a permanent shelter. The same-site exemption protects the request today. It does not protect the cookie: WebKit already caps cookies at 7 days when a first-party subdomain resolves, by CNAME or by IP address, to a third party. And the same source file that holds the domain check also holds a lookup of tracker IP address ranges supplied by WebPrivacy. A review of the June beta published by TAGGRS reported connections to bat.bing.com being cut on that basis. I could not reproduce that on 27.2, where the request was sent, so treat IP-based blocking as a capability that exists in the code and whose current scope is unknown.

Forgetting consent. Moving collection to the server changes the transport, not the legal basis. If the user refused a purpose, forwarding the event from your server instead of their browser does not make it lawful. A server-side setup needs the consent state passed with every event and enforced before forwarding.

Treating Shopify like a custom stack. On hosted platforms you do not control the origin, so a true same-origin collection path is not always available. Check what your platform allows before promising it. The constraints are covered in Shopify Web Pixels API.

Privacy protection or gatekeeping?

There are two honest ways to read this, and you will meet both in meetings.

The first is Apple’s long-standing position: cross-site identity built without the user’s knowledge is the thing tracking prevention exists to stop, and identifiers designed to replace third-party cookies are that thing under a new name. Seen that way, the list is ITP finishing its job.

The second was put forcefully by privacy lawyer Alan Chapell in an essay for Marketecture. His points, which are arguments and not established facts: outside the EU every iOS browser runs on Apple’s engine, so users are not choosing Safari’s policy; the list is secret and unilateral; Google appears to be absent from it; and Apple is building an advertising business of its own. He also notes that browsers will have to support an opt-out signal such as Global Privacy Control from January under California’s rules, which is a mechanism where the user decides rather than the browser vendor.

My own reading stays close to what can be shown. The code is public and the conditions are narrow. The list is private, it now updates silently, and the only version anyone outside Apple has seen included a competitor’s ad delivery domain for about three weeks. Both things are true. Plan for the mechanism, not for the intention.

Checklists

If you are an advertiser

  1. Run the ten-minute test on the hosts your tags call. Keep the result with the Safari version and the date.
  2. Check programmatic reports for a Safari on iOS 27 hole between September 14 and early October.
  3. Move conversion events for your main platforms to a server-side path with a same-site collection endpoint, if they are not there yet.
  4. Pass the consent state with every server-side event.
  5. Add the test to your release checklist for each Safari update.

If you are a publisher

  1. List the identity modules in your wrapper and test their hosts.
  2. Compare Safari CPM and bid density before and after your audience upgraded to iOS 27.
  3. Ask each identity and data partner, in writing, what they return on Safari 27 and what their plan is.
  4. Check which signals you can provide first-party: authenticated identifiers, contextual signals, your own segments.
  5. Watch whether your ad server or SSP domains appear in a future test run.

What I could not verify, and what to watch

Two things are worth watching. The first is the shape of the list: does it stay on identity vendors, or does it move toward ad delivery and measurement? The second is its tempo, now that an update no longer needs a release. The only reliable instrument for both is the one you have just read about: a list of hosts, a blank page, and a console.

Sources