How Chromium Batches and Sends Network Error Logs
This article provides a quick overview of how the Chromium web browser utilizes the Reporting API to collect, batch, and transmit Network Error Logging (NEL) data out-of-band. It covers the initial configuration via HTTP headers, the internal queuing mechanism that aggregates multiple error reports, the timing and grouping logic governing batch creation, and the final background delivery and retry processes used to send JSON payloads to specified collector endpoints.
Configuration and Initialization
Chromium relies on two HTTP response headers from a server to
initialize error logging: Reporting-Endpoints (or the
legacy Report-To header) and NEL. When a user
successfully connects to a site, these headers instruct the browser to
cache a reporting policy inside its network stack. This policy defines
the collector endpoint URLs, the lifespan of the configuration, and the
sampling rates for both successful and failed network requests.
Capturing and Queuing Logs
Once a policy is active, Chromium monitors all network requests made to that origin. If a network error occurs—such as a DNS resolution failure, TCP connection timeout, TLS handshake error, or HTTP 500-level response—Chromium's network stack generates a structured NEL report.
Instead of transmitting this report immediately, the network stack
passes the data to Chromium's internal ReportingService.
The service places the report into an in-memory queue. This step
decouples error generation from report transmission, ensuring the
browser does not immediately attempt to send network requests over a
connection that just proved to be unstable or offline.
The Batching Mechanism
To minimize bandwidth consumption and wake-ups on mobile devices,
Chromium batches queued reports before attempting to send them. The
ReportingService uses an internal timer to periodically
sweep the report queue.
When the delivery timer fires, Chromium executes the following batching process:
- Selection: It pulls pending reports from the queue, respecting limits on the maximum number of reports and total payload size.
- Grouping: It groups the selected reports by their origin and their designated collector endpoint URL.
- Serialization: For each group, Chromium combines the individual reports into a single JSON array.
- Age Calculation: Just before serialization, the
browser calculates how long each report sat in the queue and populates
the
ageproperty (in milliseconds) for every individual report object in the batch.
Because of this batching mechanism, if a single webpage fails to load twenty different image assets due to a sudden connection drop, the collector endpoint will eventually receive one HTTP request containing an array of twenty error objects, rather than twenty separate requests.
Out-of-Band Transmission
Transmission occurs "out-of-band," meaning it operates entirely in the background within Chromium's network service, independent of the lifecycle of the web page that generated the errors. Even if the user navigates away from the page or closes the tab, the queued reports remain in the browser's memory awaiting the next delivery cycle.
Chromium transmits the batched payload by dispatching an asynchronous
HTTP POST request to the configured collector endpoint.
This request is sent with the Content-Type header set to
application/reports+json. For security and privacy reasons,
these requests are uncredentialed, meaning they are stripped of cookies
and client certificates to prevent cross-site tracking via error
logs.
Failure Handling and Retries
Because NEL deals specifically with network failures, the transmission of the error report itself will frequently fail if the user's internet connection is completely down.
If the POST request to the collector endpoint fails,
Chromium does not discard the batch. Instead, it follows a strict retry
and eviction protocol:
- Exponential Backoff: The browser marks the specific collector endpoint as failing and applies an exponential backoff timer to delay future delivery attempts to that URL.
- Re-queuing: The failed reports are returned to the
in-memory queue, and an internal
attemptscounter is incremented for each report in the failed batch. - Eviction: If a report fails to send after reaching the maximum number of allowed delivery attempts, or if the in-memory queue reaches its maximum storage capacity, Chromium evicts the oldest and most-attempted reports to free up memory for new logs.
Because the entire queuing and batching system lives strictly in volatile memory for privacy and performance reasons, any batched or queued reports that have not been successfully transmitted are permanently deleted if the user completely quits the Chromium browser process.