Safari 11, Multiline HTTP Headers, and NSPOSIXErrorDomain:100.

I was happy when Mozilla announced that it was going to take a serious stab at the browser market again and released Firefox Quantum, a beta version of Firefox that runs significantly faster than the current stable version. So far I’ve been mostly impressed by it. However, Firefox Quantum has one significant flaw, it hogs the CPU. Even when idling I’ve noticed Firefox Quantum processes taking anywhere from five to 20 percent of the available power on one of my CPU cores. I decide to compare this CPU usage against Chrome and Safari, which lead me down quite the rabbit hole.

It all started when I tried to load my blog in Safari. Previous versions of Safari haven’t had any difficulty loading my site but when I tried to load it in Safari 11 I received the following error:

NSPOSIXErrorDomain:100 is about as useless as an error message can get. Unfortunately, Google didn’t provide me much insight. After a series of Google searches I did come across this article, which discusses some problems previous versions of Safari have had with Content Security Policies (CSP). Since I implemented a CSP for this site, I figured it was a good place to start. Low and behold, when I disabled my CSP the site loaded in Safari again.

This confused me since, as I mentioned earlier, my site, with its current CSP, loaded in previous versions of Safari. I thought that maybe one of the fields in my CSP had been deprecated or was misconfigured, which lead me to testing with a very simple one line CSP. When I tested with the simplified CSP my site loaded again. When I added an additional line to my CSP the site stopped loading again. That lead me to suspect the line feed characters. I split my CSP into multiple lines to make it easier to read and edit so it looked like this:

add_header Content-Security-Policy "default-src 'self';
  script-src 'self' 'unsafe-inline' 'unsafe-eval' https://s0.wp.com https://s1.wp.com https://s2.wp.com https://stats.wp.com;
  img-src 'self' https://secure.gravatar.com https://s0.wp.com https://s1.wp.com https://s2.wp.com https://chart.googleapis.com;
  style-src 'self' 'unsafe-inline' https://fonts.googleapi.com;
  font-src 'self' data: https://fonts.gstatic.com;
  object-src 'none';
  media-src 'self';
  child-src 'self' https://www.youtube-nocookie.com https://akismet.com;
  form-action 'self';";

I know it looks a little wonky since it includes unrecommended values like ‘unsafe-inline’ and ‘unsafe-eval’ for script-src but those, as well as a few other odd values such as the ‘data:’ font-src value, are needed by WordPress, which was developed before CSPs were a thing. But I digress. I decided to collapse the entire HTTP header value into a single line so it looked like this:

add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://s0.wp.com https://s1.wp.com https://s2.wp.com https://stats.wp.com; img-src 'self' https://secure.gravatar.com https://s0.wp.com https://s1.wp.com https://s2.wp.com https://chart.googleapis.com; style-src 'self' 'unsafe-inline' https://fonts.googleapi.com; font-src 'self' data: https://fonts.gstatic.com; object-src 'none'; media-src 'self'; child-src 'self' https://www.youtube-nocookie.com https://akismet.com; form-action 'self';";

After I did that my site loaded in Safari again. Then I reverted my configuration to the original multiline version but changed the standard UNIX new line character \n to the Windows (which is also the standard for the web) \r\n. After I did that my site failed to load again. Safari simply didn’t like new line characters appearing in a header entry.

It seemed that Safari 11 was unhappy with something that every other browser, including its predecessors, are still perfectly happy with. I suspected this was a bug in Safari but decided to do some digging before submitting a bug report. This was a good choice because I was mistaken. Searching for information about multiline headers lead me to this entry on Stack Overflow, which lead me to RFC 7230. Amongst other things, RFC 7230 deprecated multiline header fields:

Historically, HTTP header field values could be extended over multiple lines by preceding each extra line with at least one space or horizontal tab (obs-fold). This specification deprecates such line folding except within the message/http media type (Section 8.3.1). A sender MUST NOT generate a message that includes line folding (i.e., that has any field-value that contains a match to the obs-fold rule) unless the message is intended for packaging within the message/http media type.

It turns out that Safari 11 is adhering strictly to RFC 7230. And as of this writing it’s the only browser doing so. It also turns out that I’ve been unknowingly writing my CSP against the HTTP standard all along.

The moral of the story is if Safari 11 throws an NSPOSIXErrorDomain:100 error, check your HTTP headers to ensure they don’t contain multiline values.

Oh, and if you’re wondering, Safari 11 uses significantly less CPU power than Firefox Quantum. Chrome also uses significantly less CPU power than Firefox Quantum. But it’s worth noting that Firefox Quantum is beta software and its CPU usage may improve before its final release.

One thought on “Safari 11, Multiline HTTP Headers, and NSPOSIXErrorDomain:100.”

  1. Hey Christopher,
    thanks for the interesting article. I just tested multiline headers with nginx myself and it seems all major browsers now refuse to load the page.

    Firefox, Edge and Safari refuse. Chrome works at the moment but Chrome Dev shows a protocol error. I’m not sure if this is an error or the intended behavior for the next stable Chrome version.

Comments are closed.