Technical audit · 2026-06-23

bol.com

Website of bol, the largest Dutch online retailer

Bol.com is the largest online retailer in the Netherlands and Belgium. Homepage scan: 160 requests, 8 domains; accessed via a redirect from www.bol.com to /nl/nl/. The third-party commercial layer is handled correctly: the loaders for Google Analytics and the Facebook pixel are served from bol's primary CDN, but in a clean session send no beacons — no requests to google-analytics, facebook, or doubleclick for ads; the Google Publisher Tag library loads at 2632 ms but serves no ads. The site has its own consent mechanism (Consent UI, 2638 ms). But before consent, bol's own analytics fires: the logging service (2109 ms), an event bundle (15880 ms), and Firefly measurement with a session identifier (51370 ms). Primary behavioral data collection and measurement are non-technical purposes requiring consent, and here they fire before it is given.

Timeline of the leak

1253 ms · bot protection
Akamai's bot-protection mechanism fires (a sensor on bol's own domain). This is a security measure, not tracking.
2109 ms · own logging
A request goes out to bol's own logging service. This happens before any user choice.
2125 ms · error monitoring
A technical error/status envelope goes out to a self-hosted Sentry collector (EU region). A technical tool, not marketing.
2632 ms · Google ad-server library
Google Publisher Tag (gpt.js) loads — Google's ad-server library. Importantly, it does not request ads — there is no request to doubleclick in the scan, and no ads are served.
2638 ms · consent mechanism
Bol's own consent mechanism (Consent UI) loads. What fires before this determines what happens before consent.
5748–5751 ms · pixel and analytics loaders
Loader scripts for the Facebook pixel (5748 ms) and Google Analytics (5751 ms) load from bol's primary CDN. Importantly, neither sent a beacon in the clean session — the scan contains no requests to facebook or google-analytics.
15880 ms · own event bundle
An event bundle goes out to bol's own collector. This is primary behavioral data collection, before consent.
51370 ms · own Firefly measurement
A request with a session identifier goes out to bol's own measurement service (Firefly). This is primary measurement, and it fires before consent.
consent mechanism present, third-party commercial beacons gated on consent, but own analytics had already fired
Bol's own consent mechanism is present, and the third-party commercial layer is held behind it: the Google Analytics and Facebook pixel loaders, along with the ad-server library, load but send no commercial beacons and serve no ads. But by this point, bol's own analytics and measurement had already fired — before any user choice.

Declared versus actual

Advertising and personalization — gated on consent (policy) — заявлен
Transmission to Facebook — gated on consent (policy) — заявлен
+ Bol's own analytics and measurement (Firefly, logging, event bundle) — не заявлен

Detected trackers

Indicators of GDPR non-compliance

Context

www.bol.com is the largest online retailer in the Netherlands and Belgium (a marketplace with its own product range and partner sellers, an account area, and a delivery program). The data controller is bol.com b.v. (Utrecht, Netherlands). The site is commercial.

Scan: 160 requests to 8 domains, homepage, captured in a clean browser without a VPN or ad blocker; accessed via a redirect from www.bol.com to /nl/nl/. A key feature is that almost all domains are first-party — the site operates as a closed ecosystem. The site has its own consent mechanism.

Who receives the data

There are no third-party commercial data recipients before consent in this session.

Data largely stays within bol’s own infrastructure: bol’s own logging service, its own event bundle, and its own measurement service (Firefly) collect data on bol’s domains. The loaders for Google Analytics and the Facebook pixel are served from bol’s primary CDN and, in the clean session, send no beacons at all: the scan contains no requests to google-analytics, facebook, or doubleclick. The Google Publisher Tag ad-server library loads but serves no ads. Among third parties, only Sentry error monitoring (technical), Akamai bot protection, and image delivery from the content-management system fire before consent.

Yes, the site has its own consent mechanism (Consent UI, loads at 2638 ms), and the third-party commercial layer is held behind it: in the clean, no-consent session, the analytics and pixel loaders, along with the ad-server library, loaded but sent no commercial beacons and served no ads. This is consistent with bol’s policy, which explicitly conditions advertising, personalization, and data transmission to Facebook on prior consent.

The key issue is that bol’s own analytics fired earlier: logging (2109 ms), the event bundle (15880 ms), and Firefly measurement (51370 ms) went out before consent.

Before the user’s choice, the following fire:

  • bol’s own logging (2109 ms);
  • bol’s own event bundle (15880 ms);
  • bol’s own Firefly measurement with a session identifier (51370 ms);
  • Akamai bot protection (1253 ms) — technical;
  • Sentry error monitoring (2125 ms) — technical;
  • Google’s ad-server library (2632 ms) — loads but serves no ads;
  • Facebook pixel and Google Analytics loaders (5748–5751 ms) — load but send no beacons.

Bot protection and error monitoring raise no concerns — these are technical and security purposes. The analytics loaders, pixel loader, and ad-server library deployed nothing without consent — this works in the site’s favor. The concern is bol’s own analytics and measurement: this is primary behavioral data collection, and it fires before consent.

Why “first-party” is not a free pass

This point matters for understanding the issue. The fact that bol doesn’t transmit data to a swarm of third-party advertisers is indeed better than a scatter of external trackers. But legally, the question isn’t who receives the data — it’s on what legal basis it’s collected. First-party behavioral analytics and measurement are purposes requiring consent, and bol’s own policy explicitly classifies advertising and personalization as consent-based processing. Launching this data collection before consent contradicts both the rule and the site’s own documentation. The third-party commercial layer, meanwhile, is held correctly — and that is exactly how the first-party analytics should be handled too.

Conclusion

Bol.com is an example of a closed ecosystem where the third-party commercial layer is handled correctly: the loaders for Google Analytics, the Facebook pixel, and the ad-server library load but send no beacons and serve no ads without consent. This favorably distinguishes the site. But bol’s own analytics, logging, and Firefly measurement collect data before consent, even though bol’s own policy classifies advertising and personalization as consent-based processing. The key takeaway for the reader: the absence of third-party recipients does not eliminate the consent requirement — first-party analytics and measurement must wait for it, just as the third-party layer is already held back. It would be enough to gate their launch on consent as well.

Evidence
Original (audit)
HAR file: nl/bol-com-2026-06-23.har
SHA-256: c0d90742886567234cf5719e028511240b4b727feb2050415fcf173923c7928a
Re-check snapshot
Awaiting changes
HAR files are stored on EU infrastructure (Proton Drive). SHA-256 is published for integrity verification.
IMPORTANT: before filing a complaint with the regulator, first contact the company directly and give it 30 days to respond. Without this step the regulator may reject the complaint. Details and a template letter to the company are in the Methodology.
Ready-to-send complaint letter

Where to file: Dutch Data Protection Authority (AP)autoriteitpersoonsgegevens.nl

To: Dutch Data Protection Authority (AP)
From: [Your name], [contact email]

1. Subject of the complaint
I am filing a complaint regarding the processing of my personal data by the website bol.com.

2. Circumstances
I visited the website bol.com and found indications that the processing of my personal data does not comply with the GDPR. The technical analysis published on gdpru.eu on 23 June 2026 (open methodology, reproducible measurements) documents the following indications:

1) The site is built largely on its own infrastructure, and the third-party commercial layer is handled correctly: the loaders for Google Analytics and the Facebook pixel are served from bol's primary CDN, but in a clean session send no beacons at all — the scan contains no requests to google-analytics, facebook, or doubleclick; the Google Publisher Tag library loads but serves no ads. This works in the site's favor. However, in that same clean session, without any user choice, bol's own analytics fires. At 2109 ms, a request goes to bol's own logging service; at 15880 ms, an event bundle goes to its own collector; and at 51370 ms, bol's own measurement service (Firefly) sends a request with a session identifier. This is primary behavioral data collection and measurement — a non-technical purpose requiring consent under art. 11.7a Telecommunicatiewet and Art. 6(1)(a) GDPR. Bol's own policy explicitly conditions advertising and personalization on prior consent — meaning the platform recognizes consent as the legal basis — yet its own analytics and measurement fire before that consent. The fact that most data stays first-party and doesn't spread to third-party ad networks does not exempt it from the consent requirement: analytics and measurement, even first-party, must wait for it.

Full technical documentation is published at: https://gdpru.eu/en/audits/nl-bol-com/

3. Provisions violated
Art. 6(1)(a) GDPR and art. 11.7a Telecommunicatiewet — own analytics and measurement run before consent

4. Request
I request that you investigate the violations described and apply the measures provided for in Article 58(2) GDPR.

5. Attachments
The full evidence base — the HAR file, its SHA-256 checksum and the quotation from the site's privacy policy documenting the stated contradiction — is published and verifiable at the link in point 2 above.

[Date]                                    [Signature / name]