It's late. Do you know what your website is up to?

Network Error Logging

Preliminaries

Enlist the browser's support in keeping your website up and running. Get notifications when DNS, TLS or HTTP errors unexpectedly occur for your visitors.

It is a fact that networks are unreliable. Much of this is out of your control, and unfortunately, there is very little feedback sent to you, as the server administrator, about network problems that your visitors are experiencing.

But not everything is doomed. The network-error-logging response header can help alleviate this lack of data. It enlists the support of the visitor's browser to send reports back to you when problems occur.

Three types of errors can be sent, related to: 1) DNS misconfigurations, 2) TLS certificate validity, and 3) HTTP 400 and 500 response codes.

As of this writing (2019), this is an experimental technology, governed by a working draft specification. There is no fine-tuned control over which of these errors are reported. By enabling network-error-logging you are subscribing to all reports generated by the browser.

You subscribe to receiving these reports by attaching a network-error-logging header when responding to any request for an HTML document. There's a built-in Catch-22 here. In order for a visitor's browser to send problem reports to your reporting endpoint, it must first successfully make its way through the DNS, TLS, HTTP stack and process a valid HTTP response header. When testing your deployment of this header, be aware of this.

Upon receipt of any network-error-logging header, the browser will record and begin to use the specified instructions for all subsequent errors for all documents coming from your website's domain (protocol + hostname + port). The browser will continue to do this, for the period of time that you specify in the max-age portion of the header.

The network-error-logging header specifies a report-to value, which references a report group, defined in a separate report-to response header. Every network-error-logging header should have a report-to value.

The report-to header specifies an endpoint that is responsible for accepting and processing the reports sent to it by the browser. Reports are sent as JSON-encoded HTTP POSTs. See the separate note about policy reports for details.

The report-to rule declaration is simple, but its actual setup (with respect to the report-to response header) can be tricky to get right. Refer to the separate note about the report to header.

Configuration

The network-error-logging section is configured subordinate to the policies section. It comprises two required settings, and three optional settings.

The required settings are:

  • report-to which is the name of a group referenced in a separate report-to configuration.
  • max-age which is the length of time (in seconds) that the browser should keep monitoring your domain for network errors.

The optional settings are:

  • include-subdomains which will instruct the browser to also monitor subdomains of your website.
  • failure-fraction which defines a sampling rate — expressed as a number from 0.0 to 1.0 — that should be applied to reports about failed network requests to your website. For example, when a value of 0.1 is specified, the browser will only send a report to the policy report endpoint after every 10 failed requests. When not specified, the browser will send a policy report on every failure.
  • success-fraction which defines a sampling rate — expressed as a number from 0.0 to 1.0 — that should be applied to reports about successful network requests to your website. For example, when a value of 0.01 is specified, the browser will send a report to the policy report endpoint after every 100 successful requests. When not specified, no success reports will be sent.

To be effective, the policies module must be turned on.

EBNF

SP ::= U+20
CR ::= U+0D
QUOTATION-MARK ::= U+22
APOSTROPHE ::= U+27
ASTERISK ::= U+2A
COMMA ::= U+2C
HYPHEN ::= U+2D
FULL-STOP ::= U+2E
EQUALS-SIGN ::= U+3D
LEFT-CURLY-BRACKET ::= U+7B
RIGHT-CURLY-BRACKET ::= U+7D
parameters
report-group ::= (ALPHA | DIGIT | HYPHEN)*
report-to ::= 'report-to' SP report-group CR
max-age ::= 'max-age' SP DIGIT* CR
include-subdomains ::= 'include-subdomains' CR
failure-fraction ::= 'failure-fraction' SP ('0' | '1') FULL-STOP DIGITS* CR
success-fraction ::= 'success-fraction' SP ('0' | '1') FULL-STOP DIGITS* CR
sections
network-error-logging ::= 'network-error-logging' SP LEFT-CURLY-BRACKET CR
(report-to | max-age | include-subdomains | failure-fraction | success-fraction)*
RIGHT-CURLY-BRACKET CR
policy-configs ::= referrer-policy | content-security-policy | feature-policy | network-error-logging | report-to
policies-section ::= 'policies' SP LEFT-CURLY-BRACKET CR
policy-configs*
RIGHT-CURLY-BRACKET CR

† These are defined in separate notes

Cookbook

Example 1: minimal configuration
server {
modules {
policies on
}
policies {
network-error-logging {
report-to nel-endpoint
max-age 2592000 // 30 days
}
report-to {
nel-endpoint {
endpoint `https://domain.tld/nel-reports`
max-age 2592000
}
}
}
}
Example 2: configuring reports based on sampling rate
server {
modules {
policies on
}
policies {
network-error-logging {
report-to nel-endpoint
max-age 2592000
failure-fraction 0.1
success-fraction 0.01
}
report-to {
nel-endpoint {
endpoint `https://domain.tld/nel-reports`
max-age 2592000
}
}
}
}

Review

Key points to remember:

  • The policies module must be on to enable network error logging.
  • The network-error-logging response header is only sent when an HTML document is requested.
  • The browser can only report failures when there has been at least one successfully processed request.

It's late. Do you know what your website is up to?