Skip to main content Skip to sidebar

Understanding HTTP Network Error Logging (NEL)

Network reliability is crucial for modern web applications, but understanding when and why network requests fail can be challenging. HTTP Network Error Logging (NEL) is a W3C specification that enables websites to collect information about failed network requests from real users, providing insights into connectivity issues that might otherwise go unnoticed.

What is Network Error Logging?

Network Error Logging (NEL) is a mechanism that allows web servers to instruct browsers to collect and report network-level errors. Unlike traditional application monitoring that only tracks requests that reach your server, NEL captures failures that occur before the request even completes - such as DNS failures, connection timeouts, TLS handshake errors, and other network-level issues.

When a browser encounters these types of errors, it can automatically send a report to a specified endpoint, giving you visibility into problems that users experience but might never report manually.

How NEL Works

The NEL mechanism involves two key HTTP response headers that work together:

1. The NEL Header

The NEL header instructs the browser to monitor network requests and defines the reporting policy:

NEL: {"report_to":"nel-endpoint","max_age":604800,"success_fraction":0.01,"failure_fraction":1.0}

Complete NEL Parameters

  • report_to (required): String that references a reporting group defined in the Report-To header. This links the NEL policy to the endpoint where reports should be sent. The value must match the group field in a Report-To header.

    Example: "report_to":"nel-endpoint"

  • max_age (required): Integer specifying how long (in seconds) the browser should remember and apply this NEL policy. Once this time expires, the browser stops collecting reports until it receives a new NEL header. Common values include:

    • 86400 (1 day)
    • 604800 (7 days)
    • 2592000 (30 days)

    Setting max_age to 0 immediately disables NEL reporting for the origin.

  • success_fraction (optional, default: 0.0): Decimal value between 0.0 and 1.0 that specifies the sampling rate for successful network requests. Due to the high volume of successful requests, this is typically set very low or to 0.

    • 0.0 = Report no successful requests (recommended for most cases)
    • 0.01 = Report 1% of successful requests
    • 1.0 = Report all successful requests (only for debugging/testing)
  • failure_fraction (optional, default: 1.0): Decimal value between 0.0 and 1.0 that specifies the sampling rate for failed network requests. Since failures are typically less common than successes, this is often set to 1.0 to capture all failures.

    • 1.0 = Report all failures (recommended)
    • 0.5 = Report 50% of failures
    • 0.0 = Report no failures
  • include_subdomains (optional, default: false): Boolean that determines whether the NEL policy applies to all subdomains of the origin. When set to true, the policy covers the origin and all its subdomains.

    Example with subdomains enabled:

    NEL: {"report_to":"nel","max_age":604800,"include_subdomains":true}
    

    If set on https://example.com, this policy would also apply to:

    • https://www.example.com
    • https://api.example.com
    • https://cdn.example.com

    Important: Only use include_subdomains if you control all subdomains and have configured appropriate Report-To headers for each.

  • request_headers (optional): Array of HTTP request header names that should be included in NEL reports. This allows you to capture specific headers that might be relevant for debugging network failures.

    Example:

    NEL: {"report_to":"nel","max_age":604800,"request_headers":["User-Agent","Referer"]}
    

    Privacy note: Only request headers explicitly listed will be included. Sensitive headers like cookies or authorization are excluded by the browser regardless of configuration.

  • response_headers (optional): Array of HTTP response header names that should be included in NEL reports when available. Useful for capturing server-provided debugging information.

    Example:

    NEL: {"report_to":"nel","max_age":604800,"response_headers":["X-Request-ID","X-Cache-Status"]}
    

    These headers are only included if the request progressed far enough to receive a response. For DNS or connection failures, no response headers will be present.

Complete Example with All Parameters

NEL: {
  "report_to": "network-errors",
  "max_age": 2592000,
  "success_fraction": 0.0,
  "failure_fraction": 1.0,
  "include_subdomains": true,
  "request_headers": ["User-Agent"],
  "response_headers": ["X-Request-ID", "X-Cache-Status"]
}

This configuration:

  • Reports all failures, no successes
  • Valid for 30 days
  • Applies to all subdomains
  • Includes User-Agent from requests and X-Request-ID, X-Cache-Status from responses

2. The Report-To Header

The Report-To header defines where reports should be sent:

Report-To: {"group":"nel-endpoint","max_age":604800,"endpoints":[{"url":"https://collector.example.com/reports"}]}

Key parameters:

  • group: A name for this reporting endpoint group
  • max_age: How long the browser should cache this configuration
  • endpoints: Array of URLs where reports should be sent

Types of Errors Captured

NEL can capture various network-level failures:

DNS Resolution Errors

  • DNS name resolution failures
  • DNS timeout errors
  • No DNS response

Connection Errors

  • Connection refused
  • Connection timeout
  • Connection reset
  • Network unreachable

TLS/SSL Errors

  • Certificate validation failures
  • TLS handshake timeouts
  • Protocol version mismatches
  • Cipher suite negotiation failures

HTTP Protocol Errors

  • HTTP protocol errors
  • Response abandoned (connection closed before complete)
  • Incomplete responses

Report Structure

When a network error occurs, the browser sends a JSON report to the specified endpoint:

{
  "age": 142,
  "type": "network-error",
  "url": "https://example.com/api/data",
  "body": {
    "elapsed_time": 5000,
    "method": "GET",
    "phase": "connection",
    "protocol": "http/1.1",
    "referrer": "https://example.com/",
    "sampling_fraction": 1.0,
    "server_ip": "203.0.113.42",
    "status_code": 0,
    "type": "tcp.refused"
  }
}

Report Fields Description

FieldLocationDescription
ageTop-levelThe number of milliseconds between the report being generated and its transmission to the collector. Helps understand delays in report delivery.
typeTop-levelAlways set to "network-error" for NEL reports. Distinguishes NEL reports from other Reporting API types (CSP violations, deprecation warnings, etc.).
urlTop-levelThe full URL that experienced the network error. The address the browser was attempting to reach when the failure occurred.
elapsed_timeBodyTime in milliseconds from request initiation until error occurrence. For DNS failures, represents DNS lookup time. For connection failures, includes DNS time plus connection attempt time. Identifies whether failures are quick (immediate rejection) or slow (timeouts).
methodBodyThe HTTP method used for the request (GET, POST, PUT, DELETE, etc.). Useful for understanding if certain request types are more prone to failures.
phaseBodyStage where the request failed: dns (DNS resolution), connection (TCP connection establishment), or application (after connection established during HTTP exchange). Crucial for diagnosing where in the network stack problems occur.
protocolBodyNetwork protocol being used: http/1.1, h2 (HTTP/2), or h3 (HTTP/3). Helps identify protocol-specific issues.
referrerBodyURL of the page that initiated the request. Provides context about where users were when encountering the error and helps trace navigation paths leading to failures.
sampling_fractionBodySampling rate in effect when this report was generated (0.0 to 1.0). If failure_fraction is 0.5, this shows 0.5, meaning only 50% of failures are reported. Essential for accurately extrapolating total failure counts.
server_ipBodyIP address the browser attempted to connect to. Only present if DNS resolution succeeded. Invaluable for identifying issues with specific server IPs, such as when one server in a pool is malfunctioning or unreachable.
status_codeBodyHTTP status code returned by the server if the request progressed far enough to receive one. For most network errors (connection refused, DNS failures), this is 0 because no HTTP response was received. Non-zero values indicate connection succeeded but HTTP layer encountered an issue.
typeBodySpecific error type. Common values: dns.name_not_resolved, dns.timed_out, tcp.refused, tcp.timed_out, tcp.closed, tcp.reset, tcp.aborted, tls.cert.name_invalid, tls.cert.date_invalid, http.protocol.error, http.response.invalid, abandoned. Understanding error types helps prioritize fixes and identify failure patterns.

Use Cases

Network Error Logging provides visibility into failures that traditional monitoring systems miss. Here are the primary scenarios where NEL proves invaluable:

Regional and Geographic Issues: NEL reports can reveal if users in specific geographic regions experience connectivity problems due to ISP routing issues, regional network outages, or CDN edge node failures. By analyzing the distribution of errors across different locations, you can identify regional infrastructure problems before they escalate.

DNS Resolution Problems: DNS failures often go unnoticed by server-side monitoring since the request never reaches your infrastructure. NEL captures these DNS errors, allowing you to detect DNS provider outages, misconfigured records, or DNS poisoning attempts early. You’ll see increased dns.name_not_resolved or dns.timed_out errors before the issue affects a significant portion of your user base.

Certificate and TLS Issues: Certificate problems like expired certificates, invalid certificate chains, or hostname mismatches are immediately visible through NEL reports. This is particularly useful for detecting certificate renewal failures or CDN configuration issues that might only affect specific edge locations. You can also identify client-side problems like incorrect system clocks that cause certificate validation failures.

Infrastructure Performance: NEL helps identify connection timeouts, refused connections, and server overload issues across your infrastructure. If certain servers or load balancers start refusing connections or timing out, NEL reports will show patterns in the server_ip field, helping you pinpoint problematic hosts even when they’re behind load balancers or CDNs.

Attack Detection and Mitigation: Unusual patterns in network error reports can indicate ongoing DDoS attacks, network-level attacks, or infrastructure issues. A sudden spike in connection refused errors might indicate rate limiting or firewall changes, while patterns of TLS errors could suggest man-in-the-middle attack attempts.

Privacy Considerations

NEL is designed with privacy in mind:

  • Reports are sent without credentials (no cookies or authentication headers)
  • The browser can apply its own sampling rate on top of the server’s configuration
  • Users can disable NEL through browser settings or extensions
  • Reports are batched and sent asynchronously to minimize performance impact

Browser Support

NEL is supported by modern browsers:

  • Chrome/Edge: Full support (Chromium 69+)
  • Firefox: Not yet implemented (as of 2025)
  • Safari: Not yet implemented
  • Opera: Full support (Chromium-based)

Despite limited browser support, NEL can still provide valuable insights from the significant portion of users on Chromium-based browsers.

Example Configurations

Basic Configuration

A minimal setup for production websites:

NEL: {"report_to":"network-errors","max_age":604800,"success_fraction":0,"failure_fraction":1.0}
Report-To: {"group":"network-errors","max_age":604800,"endpoints":[{"url":"https://reports.example.com/nel"}]}

This configuration:

  • Reports all network failures (failure_fraction=1.0)
  • Does not report successful requests (success_fraction=0)
  • Maintains the policy for 7 days (max_age=604800)
  • Sends reports to a dedicated collection endpoint

Configuration with Subdomains

For organizations managing multiple subdomains:

NEL: {"report_to":"nel","max_age":2592000,"failure_fraction":1.0,"include_subdomains":true}
Report-To: {"group":"nel","max_age":2592000,"endpoints":[{"url":"https://collector.example.com/nel"}]}

This applies the NEL policy to all subdomains for 30 days.

Advanced Configuration with Headers

For detailed debugging with request and response headers:

NEL: {
  "report_to":"nel-debug",
  "max_age":604800,
  "success_fraction":0,
  "failure_fraction":1.0,
  "request_headers":["User-Agent","Referer"],
  "response_headers":["X-Request-ID","X-Cache-Status","X-Served-By"]
}
Report-To: {
  "group":"nel-debug",
  "max_age":604800,
  "endpoints":[{"url":"https://reports.example.com/nel/debug"}]
}

This configuration includes specific headers in reports to aid in troubleshooting.

Testing Configuration

For initial testing with sampling:

NEL: {"report_to":"nel-test","max_age":86400,"success_fraction":0.01,"failure_fraction":0.1}
Report-To: {"group":"nel-test","max_age":86400,"endpoints":[{"url":"https://test-collector.example.com/nel"}]}

This configuration:

  • Reports 1% of successful requests and 10% of failures
  • Short 1-day policy for quick iterations
  • Uses a test endpoint to avoid mixing with production data

Conclusion

HTTP Network Error Logging provides powerful visibility into network-level failures that affect your users but often go undetected by application monitoring. By implementing NEL, you can proactively identify and resolve connectivity issues, improve service reliability, and better understand the real-world network conditions your users experience.

While browser support is currently limited to Chromium-based browsers, the insights from this significant user segment can be invaluable for maintaining a reliable web service. As the specification matures and gains broader adoption, NEL will become an essential tool in every web operations toolkit.

References