Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
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.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the Web Performance Working Group as a Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-web-perf@w3.org (subscribe, archives). All comments are welcome.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 September 2015 W3C Process Document.
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. 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. To take advantage of NEL, a web application opts into using NEL by supplying a NEL
HTTP response header field that describes the reporting policy. Then, if the NEL policy is available for a given origin, and an end user fails to successfully fetch a resource from that origin, the user agent logs the network error report and attempts to deliver it to the report URL defined by the policy - the delivery is done on a best effort basis and might be delayed due to connectivity issues or other reasons.
For example, if the user agent fails to fetch a resource from https://www.example.com
due to an aborted TCP connection, the user agent would notify the report URL defined by the NEL policy associated with that origin, by delivering the following report:
{ "nel-report": [ { "uri": "https://www.example.com/resource", "referrer": "https://referrer.com/", "server-ip": "123.122.121.120", "elapsed-time": 321, "age": 0, "type": "tcp.aborted" } ] }
See reporting for explanation of the communicated fields and format of the report, and examples for more hands-on examples of NEL registration and reporting process.
The server delivers the NEL policy to the user agent via an HTTP response header field (NEL header field). If the result of executing is-origin-trusworthy algorithm ([POWERFUL-FEATURES]) on origin that served the NEL policy is Potentially Trustworthy
then the user agent MUST either:
Otherwise, if the result of the algorithm is not Potentionally Trustworthy
, then the user MUST ignore the provided NEL policy.
NEL
Header FieldThe NEL header field is used to communicate the NEL policy to the user agent. The ABNF (Augmented Backus-Naur Form) syntax for the NEL header field is as follows:
NEL = "NEL" ":" [ directive ] *( ";" [ directive ] ) directive = directive-name [ "=" directive-value ] directive-name = token directive-value = token | quoted-string
See [RFC7230] section 3.2.6 for definitions of token
and quoted-string
. This specification defines three NEL directives: report-uri, max-age, and includeSubDomains. The overall requirements for directives are:
User agents MUST ignore any unknown or invalid directive(s), or other header field value data, that does not conform to the syntax defined in this specification. A valid NEL header field MUST, at a minimum, contain all of the "REQUIRED" directives defined in this specification.
The user agent MUST ignore the NEL header specified via a meta
element to mitigate hijacking of error reporting via scripting attacks. The NEL policy MUST be delivered via the NEL header field.
The restriction on meta
element is consistent with [CSP] specification, which restricts reporting registration to HTTP header fields only for same reasons.
report-uri
DirectiveThe report-uri directive specifies a URL to which the user agent sends reports about network errors. The report-uri directive is a REQUIRED field to register an NEL policy, and OPTIONAL if the intent is to remove a previous registration - see max-age. The ABNF grammar for the name and value of the directive is:
directive-name = "report-uri" directive-value = 1*absolute-URI
The set of report URLs is the value of the report-uri directive, which contains one or more absolute-URI
's - see [RFC3986] section 4.3. Each absolute-URI
value SHOULD be delimited within double-quotes.
The result of executing the is-origin-trustworthy algorithm on origin of each report URL in the provided set of report URLs MUST return Potentially Trustworthy
. Report URL's that fail this criteria MUST be ignored by the user agent. The process of sending network error reports to the specified URL's in this directive's value is defined in this documents 2.4 Reporting section.
To improve delivery of NEL reports the application should set report-uri
to 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 report-uri
's to provide fallback alternatives if the preceding report-uri
is unreachable.
max-age
DirectiveThe REQUIRED max-age directive specifies the number of seconds, after the reception of the NEL header field, during which the user agent regards the host (from whom the policy was received) as a known NEL origin. The ABNF grammar for the name and value of the directive is:
directive-name = "max-age" directive-value = delta-seconds
See [RFC7234] section 1.2.1 for definition of delta-seconds
. A max-age value of zero (i.e. "max-age=0") signals the user agent to cease regarding the host as a known NEL origin, including the includeSubDomains directive if provided.
includeSubDomains
DirectiveThe OPTIONAL includeSubDomains directive is a valueless directive that, if present, signals the user agent that the NEL policy applies not only to the origin that served the resource representation, but also to any origin whose host component is a subdomain of the host component of the resource representation’s origin.
An HTTP host declares itself an NEL origin by issuing an NEL policy, which is communicated via the NEL header field from a Potentially Trustworthy
origin. Upon error-free receipt and processing of this header by a conformant user agent, the user agent regards the host as a known NEL origin.
The user agent MUST maintain the NEL policy of any given NEL origin separately from any NEL policies issued by any other NEL origins. Only the given NEL origin can update or cause deletion of its NEL policy. This is accomplished by sending a NEL header field to the user agent with new values for the policy report URL, time duration, and subdomain applicability. Thus, the user agent MUST store the "freshest" NEL policy information on behalf of an NEL origin, and specifying a zero time duration MUST cause the user agent to delete the NEL policy (including any asserted includeSubDomains directive) for that NEL origin.
A network error is any condition where a connection or a protocol error is encountered by the user agent, thus preventing it from successfully completing the request-response exchange. This may include, but is not limited to DNS, TCP, TLS, and HTTP connection and protocol errors. For example, a network error is triggered when the user agent:
The user agent MAY classify and report server error responses (5xx status code, [RFC7231]) as network errors. For example, a network error report may be triggered when a fetch fails due to proxy or gateway errors, service downtime, and other types of server errors.
The failure to fetch a resource when the user agent is known to be offline (when navigator.onLine
returns false
) MUST NOT be considered to be a network error.
Note that the above definition of "network error" is different from definition in [Fetch]. The definition of network error in this specification is a subset of [Fetch] definition - i.e. all of the above conditions would trigger a "network error" in [Fetch] processing, but conditions such as blocked requests due to mixed content, CORS failures, etc., would not.
When a network error occurs for a URL that belongs to a known NEL origin the user agent SHOULD log the error and attempt to deliver it to the report URL defined by the NEL policy of the associated NEL origin:
To generate a network error object, the user agent MUST use an algorithm equivalent to the following:
x:x:x:x:x:x:x:x
, where the 'x's are one to four hexadecimal digits of the eight 16-bit pieces of the address). [RFC4291] The user agent MAY extend the above error type list with custom values - e.g. new error types 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]
) 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.
To send network error reports, the user agent MUST use an algorithm equivalent to the following:
Content-Type
header field of application/nel-report
, and an entity body consisting of report body. If the origin of report URL is not the same as the origin of the NEL origin for which the report is generated, the block cookies flag MUST also be set. The task source for these tasks is the Network Error Logging task source.The user agent is allowed to garbage collect report-uri's that are no longer functional, but it should account for common failure cases such as captive portals, which may temporarily prevent it from delivering the error reports. The exact implementation logic is deferred to the user-agent, which may use own mechanisms and heuristics to detect such cases.
> GET / HTTP/1.1 > Host: example.com < HTTP/1.1 200 OK < ... < NEL: report-uri="https://example.com/report"; max-age=2592000
The above NEL policy provided in the server response specifies that the user agent should register a new NEL policy, or update an existing one if one already exists, for the example.com
NEL origin: the user agent should report network errors to https://example.com/report
and the policy applies for 2592000 seconds (30 days).
Note that above registration will only succeed if the response is communicated from a Potentially Trustworthy
origin - see 2.2 Policy Delivery and Processing.
> GET / HTTP/1.1 > Host: example.com < HTTP/1.1 200 OK < ... < NEL: report-uri="https://other-origin.com/report"; max-age=2592000
The above NEL policy provided in the server response is similar to the previous example but tells the user agent to report network errors to https://other-origin.com/report
. The use of an alternative origin that is not coupled with the origin that is being accessed is strongly encouraged to enable real-time reporting and improved report delivery - see 2.2.1.1 The report-uri Directive.
> GET / HTTP/1.1 > Host: example.com < HTTP/1.1 200 OK < ... < NEL: report-uri="https://example.com/report" "https://other-origin.com/report"; max-age=2592000; includeSubDomains
The above NEL policy provided in the server response specifies that the user agent should report network errors to https://example.com/report
, or https://other-origin.com/report
if the former is unreachable. Further, the policy is extended to all of the subdomains of the issuing NEL origin - see 2.2.1.3 The includeSubDomains Directive.
> GET / HTTP/1.1 > Host: example.com < HTTP/1.1 200 OK < ... < NEL: max-age=0
The above NEL policy provided in the server response contains max-age set to zero, which indicates that the user agent must delete the current registered NEL policy associated with the example.com
NEL origin and all of its subdomains:
This section contains an example network error report the user agent might send when a network error is encountered for a known NEL origin.
{ "nel-report": [ { "uri": "https://www.example.com/", "referrer": "http://example.com/", "server-ip": "123.122.121.120", "protocol": "h2", "status-code": 200, "elapsed-time": 823, "age": 0, "type": "http.protocol.error" } ] }
The above report indicates that the user agent attempted to navigate from "example.com" to "www.example.com" (known NEL origin), which successfully resolved to the "123.122.121.120" IP address. However, while the user agent received a "200" response from the server via the "h2" protocol, it encountered a protocol error in the exchange and was forced to abandon the navigation. 823 milliseconds elapsed between the start of navigation and when the user agent aborted the navigation. Finally, the user agent sent this report immediately after the network error was encountered - i.e. the report age is 0.
{ "nel-report": [ { "uri": "https://widget.com/thing.js", "referrer": "https://www.example.com/", "server-ip": "234.233.232.231", "protocol": "", "status-code": 0, "elapsed-time": 143, "age": 0, "type": "http.dns.name_not_resolved" } ] }
The above report indicates that the user agent attempted to fetch "https://widget.com/thing.js", which belongs to a previously registered NEL origin, from "www.example.com" origin. However, the user agent was unable to resolve the DNS name and the request was aborted by the user agent after 143 milliseconds. Because "widget.com" is a known NEL origin, a network error report was logged and sent to the report URL specified by the NEL policy of that host immediately after the network error was encountered - i.e. the report age is 0.
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 relevant NEL 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 associated with a registered NEL origin, 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 the registered NEL origin, 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 users network configuration. Also, similar to HSTS, HPKP, and pinned CSP policies, the stored NEL policy could be used as a "supercookie" by setting a distinct policy with a custom (per-user) reporting URI to act as an identififer in combination with (or instead of) HTTP cookies.
To mitigate some of the above risks, NEL registration is restricted to trustworthy origins, and delivery of network error reports is similarly restricted to trustworthy origins. This disallows a transient HTTP MITM from trivially abusing NEL as a persistent tracker.
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]):
This document reuses text from the [CSP] and [RFC6797] specification, as permitted by the licenses of those specifications. Additionally, sincere thanks to Thomas Tuttle, Chris Bentzel, Todd Reifsteck, Aaron Heady, and Mark Nottingham for their helpful comments and contributions to this work.