This document defines a mechanism that enables developers to declare a network error reporting policy for a web application. A user agent can use this policy to report encountered network errors that prevented it from successfully fetching requested resources.
Accurately measuring performance characteristics of web applications is an important aspect in helping site developers understand how to improve their web applications. The worst case scenario is the failure to load the application, or a particular resource, due to a network error, and to address such failures the developer requires assistance from the user agent to identify when, where, and why such failures are occurring.
Today, application developers do not have real-time web application availability data from their end users. For example, if the user fails to load the page due to a network error, such as a failed DNS lookup, a connection timeout, a reset connection, or other reasons, the site developer is unable to detect and address this issue. Note that these kinds of network errors cannot be detected purely server-side, since by definition the client might not have been able to successfully establish a connection with the server.
Existing methods (such as synthetic monitoring) provide a partial solution by placing monitoring nodes in predetermined geographic locations, but require additional infrastructure investments, and cannot provide truly global and near real-time availability data for real end users.
Network Error Logging (NEL) addresses this need by defining a mechanism enabling web applications to declare a reporting policy that can be used by the user agent to report network errors for a given origin. A web application opts into using NEL by supplying aNEL HTTP response header field that describes the desiredNEL policy. This policy instructs the user agent to log information about requests to that origin, and to attempt to deliver that information to a group of endpoints previously configured using the [[[REPORTING]]]. As the name implies, NEL reports are primarily used to describeerrors. However, in order to determinerates of errors across different client populations, we must also know how manysuccessful requests are occurring; these successful requests can also be reported via the NEL mechanism.
For example, if the user agent fails to fetch a resource fromhttps://www.example.com due to an aborted TCP connection, the user agent would queue the following report via the Reporting API:
"network-error"{ "referrer": "https://referrer.com/", "sampling_fraction": 1.0, "server_ip": "192.0.2.42", "protocol": "http/1.1", "elapsed_time": 321, "phase": "connection", "type": "tcp.aborted"}See for an explanation of the communicated fields and format of the report, and for more hands-on examples of NEL registration and reporting process.
Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.
Some conformance requirements are phrased as requirements on attributes, methods or objects. Such requirements are to be interpreted as requirements on the user agent.
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)
Anetwork request occurs when the [=user agent=] attempts toHTTP-network fetch a resource over the network for a given [=request=].
A [=request=] MUST NOT result in anetwork request if the user agent is known to be offline (i.e., whennavigator. {{NavigatorOnLine/onLine}} returnsfalse).
A [=request=] MUST NOT result in anetwork request if it is blocked due to [=mixed content=] or [=CORS protocol|CORS=] failures. Any [=CORS-preflight request=] MUST result in its ownnetwork request.
For user agents that servicerequests according to the [[FETCH]] standard, anetwork request corresponds to one execution of theHTTP-network fetch algorithm.
Regardless of which fetch algorithm and which underlying application and transport protocols are used, servicing anetwork request consists of the followingphases:
The only mandatoryphase is thetransmission of request and response; the otherphases might not be needed for everynetwork request. For instance, DNS results can be cached locally in the user agent, eliminatingDNS resolution for future requests to the same domain. Similarly, HTTPpersistent connections allow open connections to be shared for multiple requests to the same [=network partition key=]. However, if multiplephases occur, they will occur in the above order.
We would like to move the definition of thesephases into [[FETCH]] so that they are more reusable.
Anetwork request issuccessful if the user agent is able to receive a valid HTTP response from the server, and that response does not have a4xx or5xx status code.
Anetwork request isfailed if it is notsuccessful.
Note that HTTP error responses (i.e., those with a4xx or5xx status code) are consideredfailures, so that they are subject to aNEL policy'sfailure sampling rate instead of itssuccessful sampling rate.
Anetwork error is the error condition that caused anetwork request tofail.
Eachnetwork error has atype, which is a string.
Eachnetwork error has aphase, which describes whichphase the error occurred in:
dnsconnectionapplicationThere are several predefinednetwork errortypes defined in.
Anetwork error report is a [[[REPORTING]]]report that describes anetwork error.
Network error reports have areport type ofnetwork-error.
Network error reports areNOTvisible toReportingObservers.
Network error reports are notvisible toReportingObservers because they are only intended to be visible to the administrator or owner of the serverreceiving the requests. If they werevisible toReportingObservers, then the reports would also be visible to theoriginator of the request. For cross-origin requests, this could leak information about the server's network configuration to parties outside of its control.
ANEL policy instructs a user agent whether to collect reports aboutnetwork requests to anorigin, and if so, where to send them.NEL policies are delivered to the user agent via HTTPresponse headers.
EachNEL policy has areceived IP address, which is the [=IP address=] of theserver that the user agent received thisNEL policy from.
EachNEL policy has anorigin.
EachNEL policy has asubdomains flag, which is eitherinclude orexclude.
EachNEL policy has a list ofrequest headers and a list ofresponse headers, each of which is a list ofheader names.
EachNEL policy has areporting group, which is the name of the Reportingendpoint group that reports for this policy will be sent to.
EachNEL policy has attl representing the number of seconds the policy remains valid.
EachNEL policy has acreation which is the timestamp when the user agent received the policy.
ANEL policy isstale if theduration from itscreation to the [=wall clock=]'s [=wall clock/unsafe current time=] is greater than 172800 seconds (48 hours).
ANEL policy isexpired if theduration from itscreation to the [=wall clock=]'s [=wall clock/unsafe current time=] is greater than itsttl (in seconds).
Anorigin that expects to serve a large volume of traffic might not be equipped to ingest NEL reports for everynetwork request made to the origin. The origin can definesampling rates to limit the number of NEL reports that each user agent submits. Sincesuccessful requests should typically greatly outnumberfailed requests, the origin can specify different sampling rates for each.
EachNEL policy has asuccessful sampling rate, which is a number between 0.0 and 1.0 inclusive.
EachNEL policy has afailure sampling rate, which is a number between 0.0 and 1.0 inclusive.
A conformant user agent MUST provide apolicy cache, which is a storage mechanism that maintains a set ofNEL policies, keyed by (network partition key,origin) tuples.
This storage mechanism is opaque, vendor-specific, and not exposed to the web, but it MUST provide the following methods which will be used in the algorithms this document defines:
Aserver MAY define aNEL policy for an origin it controls via theNEL HTTPresponse header.
NEL response header TheNELresponse header is used to communicate anorigin'sNEL policy to the user agent. The ABNF (Augmented Backus-Naur Form) [[RFC5234]] syntax for theNEL header is as follows:
NEL = json-field-value
The header's value is interpreted as an array of JSON objects, as defined byjson-field-value. Each object in the array defines anNEL policy for the origin. The user agent MUST process the first valid policy in the array and ignore any additional policies in the array.
User agents MUST ignore any unknown or invalid field(s) or value(s) that do not conform to the syntax defined in this specification. A validNEL header field MUST, at a minimum, contain one object with all of the "REQUIRED" fields defined in this specification.
The user agent MUST ignore theNEL header specified via ameta element to mitigate hijacking of error reporting via scripting attacks. TheNEL policy MUST be delivered via theNELresponse header.
The restriction onmeta element is consistent with the [[CSP]] specification, which restricts reporting registration to HTTP header fields only for the same reasons.
report_to member Thereport_to member specifies theendpoint group that reports for thisNEL policy will be sent to. Thereport_to member is REQUIRED to register aNEL policy, and OPTIONAL if the intent is to remove a previous registration – seemax_age. If present, its value MUST be a string; any other type will result in a parse error.
To improve delivery of NEL reports, theserver should setreport_to to anendpoint group containing at least one endpoint in an alternative origin whose infrastructure is not coupled with the origin from which the resource is being fetched — otherwise network errors cannot be reported until the problem is solved, if ever — and provide multiple endpoints to provide alternatives if some endpoints are unreachable.
max_age member The REQUIREDmax_age member specifies the lifetime of thisNEL policy, as a non-negative integer number of seconds. Its value MUST be an non-negative integer; any other type will result in a parse error.
A value of0 will cause anyNEL policy for thisorigin to be removed from thepolicy cache.
To ensure delivery of NEL reports, theserver should ensure that the Reportingendpoint group is also configured with a sufficiently highmax_age. If the Reporting policy expires, NEL reports will not be delivered, even if the NEL policy has not expired.
include_subdomains member The OPTIONALinclude_subdomains member is a boolean that enables thisNEL policy for all subdomains of this origin (to an unlimited subdomain depth). If no member namedinclude_subdomains is present in the object, or its value is nottrue, theNEL policy will not be enabled for subdomains.
To ensure delivery of NEL reports for subdomains, the application should ensure that the Reportingendpoint group is also configured withinclude_subdomains enabled. If the Reporting policy is not, and there is not a separate Reporting policy for a given subdomain, NEL reports for that subdomain will not be delivered, even if the NEL policy includes the subdomain.
success_fraction member The OPTIONALsuccess_fraction member defines thesampling rate that should be applied to reports aboutsuccessfulnetwork requests for this origin. If present, its value MUST be a number between0.0 and1.0, inclusive; any other value will result in a parse error. If this member is not present, the user agent willnot collect NEL reports aboutsuccessfulnetwork requests for this origin.
failure_fraction member The OPTIONALfailure_fraction member defines thesampling rate that should be applied to reports aboutfailednetwork requests for this origin. If present, its value MUST be a number between0.0 and1.0, inclusive; any other value will result in a parse error. If this member is not present, the user agent will collect NEL reports aboutallfailednetwork requests for this origin.
request_headers member The OPTIONALrequest_headers member defines the list ofrequest headers whosenames andvalues will be included innetwork error reports about thisorigin. If present, its value MUST be a list of strings.
response_headers member The OPTIONALresponse_headers member defines the list ofresponse headers whosenames andvalues will be included innetwork error reports about thisorigin. If present, its value MUST be a list of strings.
Given anetwork request (request) and its correspondingresponse (response), this algorithm extracts aNEL policy forrequest'sorigin, and updates thepolicy cache accordingly.
Potentially Trustworthy.NEL.NEL.0, then remove anyNEL policy from thepolicy cache whoseorigin isorigin, and skip the remaining steps.Letpolicy be a newNEL policy whose properties are set as follows:
Plumb this through more explicitly in [[FETCH]].
include ifitem has a member namedinclude_subdomains whose value istrue,exclude otherwise0.0 otherwise1.0 otherwiseGiven anetwork request (request), this algorithm determines whichNEL policy in thepolicy cache should be used to generate reports for thatnetwork request.
include, return it.no policy.Given anetwork request (request) and aNEL policy (policy), this algorithm extracts header values from the request as instructed by the policy.
Given aresponse (response) and aNEL policy (policy), this algorithm extracts header values from the response as instructed by the policy.
Given anetwork request (request) and its correspondingresponse (response), this algorithm generates a report aboutrequest if instructed to by any matchingNEL policy, and returns the report and the NEL policy. Otherwise this algorithm returns null.
Potentially Trustworthy, return null.no policy, return null.sampling_fractionelapsed_timephase"application".type"ok".phase property is notdns, append the following properties toreport body:server_ipprotocol"".phase property is notdns orconnection, append the following properties toreport body:referrermethodrequest_headersresponse_headersstatus_code0.include, andreport body'sphase property is notdns, return null.This step ensures thatsubdomainNEL policies can only be used to generate reports about subdomains of thepolicy origin during theDNS resolutionphase of arequest. See for more details.
phase property is notdns, andreport body'sserver_ip property is non-empty and not equal topolicy'sreceived IP address:phase todns.type todns.address_changed.request_headers,response_headers,status_code, andelapsed_time properties.This step "downgrades" a NEL report if the IP addresses of theserver and thepolicy don't match. This is a privacy protection, ensuring that NEL reports are only sent to the owner of the service that the report describes. If the IP addresses don't match, then the user agent can only verify that theNEL policy was sent by the owner of theorigin'sdomain name; it cannot verify that the policy was sent by the owner of theserver thisdomain name resolves to. We therefore downgrade the report to only contain information aboutDNS resolution. See and for more details.
Given a ECMAScript object (report body, usually returned fromGenerate a network error report and then augmented by the calling specification) and its matchingNEL policy (policy) andnetwork request (request), this algorithm queues the report for delivery.
Leturl berequest's URL.
Clearurl's [=url/fragment=].
Ifreport body'sphase property isdns orconnection:
Clearurl's [=url/path=] and [=url/query=].
Generate a network report given these parameters:
network-errorThere are several predefinednetwork errortypes.
The user agent MAY extend this list with customnetwork errortypes — e.g. to accommodate new protocols, or more detailed error descriptions of existing ones. When doing so, the user agent SHOULD follow the dot-delimited pattern ([group].[optional-subgroup].[error-name]) for thetype names to facilitate simple and consistent processing of the error reports — e.g. the collector may provide aggregation by category and/or one or multiple subgroups.
All of thenetwork errors in this section occur duringDNS resolution, and therefore have aphase ofdns.
dns.unreachabledns.name_not_resolveddns.faileddns.address_changed All of thenetwork errors in this section occur duringsecure connection establishment, and therefore have aphase ofconnection.
tcp.timed_outtcp.closedtcp.resettcp.refusedtcp.abortedtcp.address_invalidtcp.address_unreachabletcp.failedtls.version_or_cipher_mismatchtls.bad_client_auth_certtls.cert.name_invalidtls.cert.date_invalidtls.cert.authority_invalidtls.cert.invalidtls.cert.revokedtls.cert.pinned_key_not_in_cert_chaintls.protocol.errortls.failed All of thenetwork errors in this section occur during thetransmission of request and response, and therefore have aphase ofapplication.
http.errorhttp.protocol.errorhttp.response.invalidhttp.response.redirect_loophttp.failedabandonedunknown> GET / HTTP/1.1> Host: example.com< HTTP/1.1 200 OK< ...< Report-To: {"group": "network-errors", "max_age": 2592000, "endpoints": [{"url": "https://example.com/upload-reports"}]}< NEL: {"report_to": "network-errors", "max_age": 2592000} ThisNEL header defines aNEL policy, instructing the user agent to report network errors aboutexample.com to theendpoint group namednetwork-errors. The policy applies for 2592000 seconds (30 days).
Note that above registration will only succeed if the response is communicated from apotentially trustworthy origin.
> GET / HTTP/1.1> Host: example.com< HTTP/1.1 200 OK< ...< NEL: {"max_age": 0} ThisNEL header instructs the user agent to remove any existingNEL policy forexample.com.
This section contains examplenetwork errorreports the user agent might queue when a network error is encountered for anorigin with a registeredNEL policy. We show the full report payload that would be created by the [[REPORTING]] API when uploading the report; the payload'sbody field contains thenetwork error [=report/body|report body=].
{ "age": 0, "type": "network-error", "url": "https://www.example.com/", "body": { "sampling_fraction": 0.5, "referrer": "http://example.com/", "server_ip": "2001:DB8:0:0:0:0:0:42", "protocol": "h2", "method": "GET", "request_headers": {}, "response_headers": {}, "status_code": 200, "elapsed_time": 823, "phase": "application", "type": "http.protocol.error" }} This report indicates that the user agent attempted to navigate fromexample.com towww.example.com, which successfully resolved to2001:DB8::42. However, while the user agent received a200 response from the server via the HTTP/2 (h2) protocol, it encountered a protocol error in the exchange and was forced to abandon the navigation. The user agent aborted the navigation 823 milliseconds after it started. Finally, the user agent sent this report immediately after the network error was encountered – i.e. the report age is 0.
{ "age": 0, "type": "network-error", "url": "https://widget.com/thing.js", "body": { "sampling_fraction": 1.0, "referrer": "https://www.example.com/", "server_ip": "", "protocol": "", "method": "GET", "request_headers": {}, "response_headers": {}, "status_code": 0, "elapsed_time": 143, "phase": "dns", "type": "dns.name_not_resolved" }} The above report indicates that the user agent attempted to fetchhttps://widget.com/thing.js fromhttps://www.example.com/. However, the user agent was unable to resolve the DNS name (widget.com) and the request was aborted by the user agent after 143 milliseconds. Because a previous request towidget.com delivered a validNEL policy, the user agent generates anetwork errorreport for this request. The report was uploaded immediately after thenetwork error was encountered – i.e. the report age is 0.
> GET / HTTP/1.1> Host: example.com< HTTP/1.1 200 OK< ...< Report-To: {"group": "network-errors", "max_age": 2592000, "endpoints": [{"url": "https://example.com/upload-reports"}]}< NEL: {"report_to": "network-errors", "max_age": 2592000, "include_subdomains": true} ThisNEL header allows the owner ofexample.com to detect when they have misconfigured their DNS servers — for instance, when they have forgotten to add a new resource record resolvingnew-subdomain.example.com to an IP address. If a user agent tries to make a request tonew-subdomain.example.com, it might generate the following report:
{ "age": 0, "type": "network-error", "url": "https://new-subdomain.example.com/", "body": { "sampling_fraction": 1.0, "server_ip": "", "protocol": "http/1.1", "method": "GET", "request_headers": {}, "response_headers": {}, "status_code": 0, "elapsed_time": 48, "phase": "dns", "type": "dns.name_not_resolved" }}> GET / HTTP/1.1> Host: example.com< HTTP/1.1 200 OK< ...< Report-To: {"group": "network-errors", "max_age": 2592000, "endpoints": [{"url": "https://example.com/upload-reports"}]}< NEL: {"report_to": "network-errors", "max_age": 2592000, "success_fraction": 1.0, "request_headers": ["If-None-Match"], "response_headers": ["ETag"]}< ETag: 01234abcd In this example, the owner ofexample.com usesETag response headers to identify different versions of the resources hosted on the server. User agents can then useIf-None-Match request headers to inform the server which version of a resource is presently cached client-side, allowing the server to avoid generating and sending the content of the resource if the client's existing copy is up to date.
By includingrequest_headers andresponse_headers fields in theNEL header for this domain, the browser will include a copy of theIf-None-Match request header andETag response header in any NEL report that it creates for that request, allowing the site owner to track the effectiveness of their caching policies.
Given the above, consider the following sequence of events:
The user agent sends arequest toexample.com, and receives a successfulresponse from theserver, with anETag header indicating the version of the resource. The user agent will generate the following NEL report:
{ "age": 0, "type": "network-error", "url": "https://example.com/", "body": { "sampling_fraction": 1.0, "server_ip": "192.0.2.1", "protocol": "http/1.1", "method": "GET", "request_headers": {}, "response_headers": { "ETag": ["01234abcd"] }, "status_code": 200, "elapsed_time": 1392, "phase": "application", "type": "ok" }} Some time later, the user agent sends anotherrequest toexample.com. The user agent still has a copy of the original resource in its local cache, and includes its version in aIf-None-Match request header. The server checks this version, notices that it is still current, and sends a `304` response informing the user agent that its cached copy of the resource is still valid. The user agent will generate the following report:
{ "age": 0, "type": "network-error", "url": "https://example.com/", "body": { "sampling_fraction": 1.0, "server_ip": "192.0.2.1", "protocol": "http/1.1", "method": "GET", "request_headers": { "If-None-Match": ["01234abcd"] }, "response_headers": { "ETag": ["01234abcd"] }, "status_code": 304, "elapsed_time": 45, "phase": "application", "type": "ok" }} Even later, the user agent sends yet anotherrequest toexample.com. The user agent still has the same copy of the resource in its local cache, and includes its version in aIf-None-Match request header, as in the previous example. However, this time the server notices that there is a new version of the resource available. It generates the content of this resource, and sends it to the client, with the new version encoded in a newETag response header value. The user agent will generate the following report:
{ "age": 0, "type": "network-error", "url": "https://example.com/", "body": { "sampling_fraction": 1.0, "server_ip": "192.0.2.1", "protocol": "http/1.1", "method": "GET", "request_headers": { "If-None-Match": ["01234abcd"] }, "response_headers": { "ETag": ["56789ef01"] }, "status_code": 200, "elapsed_time": 935, "phase": "application", "type": "ok" }}Fororigins whosedomain name resolves to multiple IP addresses, NEL will sometimes "downgrade" an error report, providing less information about the cause of the error, since it cannot verify that the owner of theorigin is the same as the owner of theserver handling therequest.
As an example, assume thatexample.com is handled by threeservers, each with a different IP address. The owner of the service configures DNS to resolveexample.com to192.0.2.1,192.0.2.2, and192.0.2.3, and relies on user agents to balance their requests across these three IP addresses. The service owner delivers the followingNEL policy:
> GET / HTTP/1.1> Host: example.com< HTTP/1.1 200 OK< ...< Report-To: {"group": "network-errors", "max_age": 2592000, "endpoints": [{"url": "https://example.com/upload-reports"}]}< NEL: {"report_to": "network-errors", "max_age": 2592000, "success_fraction": 1.0, "failure_fraction": 1.0}Given the above, consider the following sequence of events:
The user agent sends arequest to192.0.2.1, and receives a successfulresponse from theserver. This response includes the aboveNEL policy, and the user agent sets the policy'sreceived IP address to192.0.2.1. Since thereceived IP address matches theserver's IP address (which it must for any successful request), it generates the following NEL report:
{ "age": 0, "type": "network-error", "url": "https://example.com/", "body": { "sampling_fraction": 1.0, "server_ip": "192.0.2.1", "protocol": "http/1.1", "method": "GET", "request_headers": {}, "response_headers": {}, "status_code": 200, "elapsed_time": 57, "phase": "application", "type": "ok" }} The user agent sends a newrequest to192.0.2.2, and receives another successfulresponse. This response also includes theNEL policy, and the user agent updates the policy'sreceived IP address to192.0.2.2. Since thereceived IP address matches theserver's IP address (which it must for any successful request), it generates the following NEL report:
{ "age": 0, "type": "network-error", "url": "https://example.com/", "body": { "sampling_fraction": 1.0, "server_ip": "192.0.2.2", "protocol": "http/1.1", "method": "GET", "request_headers": {}, "response_headers": {}, "status_code": 200, "elapsed_time": 34, "phase": "application", "type": "ok" }} The user agent then tries to send arequest to192.0.2.3, but isn't able to establish a connection to the server. The user agent still has theNEL policy in thepolicy cache, and would ideally use this policy to generate atcp.timed_out report about thefailednetwork request. However, the because policy'sreceived IP address (192.0.2.2) doesn't match the IP address that thisrequest was sent to, the user agent cannot verify that the server at192.0.2.3 is actually owned by the owners ofexample.com. The user agent must therefore downgrade the report todns.address_changed:
{ "age": 0, "type": "network-error", "url": "https://example.com/", "body": { "sampling_fraction": 1.0, "server_ip": "192.0.2.3", "protocol": "http/1.1", "method": "GET", "request_headers": {}, "response_headers": {}, "status_code": 0, "elapsed_time": 0, "phase": "dns", "type": "dns.address_changed" }} The user agent then tries to send anotherrequest to192.0.2.1, but once again isn't able to establish a connection to the server. Even though the user agent received theNEL policy from192.0.2.1 at some point in the past, the policy'sreceived IP address only records where it wasmost recently received from — in this case,192.0.2.2. The user agent must therefore downgrade the report todns.address_changed:
{ "age": 0, "type": "network-error", "url": "https://example.com/", "body": { "sampling_fraction": 1.0, "server_ip": "192.0.2.1", "protocol": "http/1.1", "method": "GET", "request_headers": {}, "response_headers": {}, "status_code": 0, "elapsed_time": 0, "phase": "dns", "type": "dns.address_changed" }}A navigation request initiated by the user (e.g. via a click on a link, direct input via the location bar, script-initiated due to user interaction, etc.) may fail due any number of connectivity reasons: DNS failure, TCP error, TLS protocol violation, and so on. These errors may be caused by network misconfiguration, transient routing issues, server downtime, malware or other attacks against the user, etc.
In such cases the destination host is often left unaware of the failed navigation since, by definition, it cannot see the request reach its infrastructure and it is unable to investigate the problem. To address this, the host can register anNEL policy with the user agent, which specifies where reports of such failures should be delivered such that they can be investigated.
A typical application requires dozens of resources, the fetching of which is typically initiated via HTML, CSS, or JavaScript. The application requesting such resources can observe failures of most such fetches (e.g. via `onerror` callbacks), but it does not have access to the detailed network error report of why the failure has occurred - e.g. DNS failure, TCP error, TLS protocol violation, etc.
To address this, the application can register relevantNEL policies with the user agent for the first-party hosts from which the subresources are being fetched. Then, if such a policy is present and a network error is encountered for a resource from anorigin with a registeredNEL policy, the user agent will report the detailed network error report and enable the application developers to investigate the error.
In the case where a resource is embedded by a third party, the provider of the resource is often unable to instrument and observe the failure. For example, if `example.com` embeds a `widget.com/thing.js` resource on its site, and the user visiting `example.com` fails to fetch such resource due to a network error, the `widget.com` host is both unaware of the failure and unable to detect it.
To address this, `widget.com` can register an NEL policy for its host. Then, if such policy is present and a network error is encountered while fetching a resource — regardless of whether it is being requested from a first-party or third-party origin — from theorigin with a registeredNEL policy, the user agent will report the network error and enable the provider to investigate the error.
NEL provides network error reports that could expose new information about the user's network configuration. For example, an attacker could abuse NEL reporting to probe the user's network configuration, or to scan for servers on the user's internal network. Also, similar to HSTS, HPKP, and pinned CSP policies, the storedNEL policy could be used as a "supercookie" by setting a distinct policy with a custom (per-user) reporting URI to act as an identifier in combination with (or instead of) HTTP cookies.
To mitigate some of the above risks, NEL registration is restricted topotentially trustworthy origins, and delivery of network error reports is similarly restricted topotentially trustworthy origins. This disallows a transient HTTP MITM from trivially abusing NEL as a persistent tracker.
Additionally, the NELpolicy cache is partitioned using thenetwork partition key, so that aNEL policy stored for a site in one embedding context will not be used in a different context (for instance, when embedded by a different top-level site.)
NEL is intended to augment existing server-side monitoring. NEL reports should only be sent to the owner of the service being requested. For errors that occur duringDNS resolution, NEL reports are only generated when theNEL policy was received from the owner of thedomain namespace tree that contains thepolicy origin. For errors that occur duringsecure connection establishment ortransmission of request and response, NEL reports are only generated when theNEL policy was received from the owner of theserver that therequest was sent to.
This rationale explains the treatment of thereceived IP address andsubdomains flag of aNEL policy. By checking that the policy'sreceived IP address matches the IP address of theserver, NEL extends the trust boundary of the policy to include not just the policy'sorigin, but also the specific server that the user agent is communicating with. This helps prevent (for instance) DNS rebinding attacks, where an attacker delivers a long-livedNEL policy from a server that they own, and then changes their name servers to resolve thepolicy origin to a server they don't control. Without thereceived IP address verification, this would cause user agents to send reports about the second server to the attacker.
Similarly,subdomainNEL policies are limited, and can only be used to generate reports about subdomains of thepolicy origin during theDNS resolutionphase of arequest. During thisphase, there is noserver to verify ownership of, and the fact that the policy was received from a superdomain of therequest'sorigin is enough to establish ownership of the error. This allows the owners of a particular portion of thedomain namespace tree to use NEL to detect errors, while preventing them from using malicious DNS entries to collect information about servers they don't control.
To prevent information leakage, NEL reports about arequest do not contain any information that is not visible to theserver when processing therequest. For errors duringDNS resolution, a NEL report only contains information available from DNS itself. This preventsservers from abusing NEL to collect more information about their users than they already have access to. Note that NEL reports will include a web site's public IP address in the [=report/body|report body=]'sserver_ip field, which may not always be known to the service which generates the NEL header, for example if it is behind a load balancer or other transparent MitM proxy.
As an example, NEL reports specifically do not contain any information about which DNSresolver was used to resolve arequest'sdomain name into an IP address.
In addition to above restrictions, the user agents MUST:
When deploying NEL the developer SHOULD consider privacy implications of NEL reports delivered to the specified collectors. For example, reports may contain URLs with sensitive data (e.g. "Capability URLs") that may need special precautions (see [[CAPABILITY-URLS]]), and may require the developer to operate their own NEL collectors to prevent reporting of such URLs to third parties.
The permanent message header field registry should be updated with the following registrations ([[RFC3864]]):
NELNELThis document reuses text from the [[CSP]] and [[RFC6797]] specification, as permitted by the licenses of those specifications. Additionally, sincere thanks to Julia Tuttle, Chris Bentzel, Todd Reifsteck, Aaron Heady, and Mark Nottingham for their helpful comments and contributions to this work.