18

I have an EC2 instance with Apache as webserver (and Wildfly as app-server, although I'm not sure it has anything to do with this issue). In front of EC2 I have a load balancer which terminates HTTPS and applies the SSL cert.

Both HTTP and HTTPS works fine in Chrome, but unfortunately not in Safari. Accessing http://test.papereed.com works fine, but accessing https://test.papereed.com gives the error

"Safari can't open the page. The error is "The operation couldn't be completed. Protocol error" (NSPOSIXErrorDomain:100)"

I've looked in /etc/httpd/logs/error_log and /etc/httpd/logs/access_log and also in the Safari console without finding any hint to solving the problem. And that's about how far my knowledge goes :-( Any hints how to trace this issue would be much appreciated.

Tim
  • 30,383
  • 6
  • 47
  • 77
jola
  • 377
  • 1
  • 3
  • 11

4 Answers4

26

curl (if compiled with HTTP/2 support) exhibits the same problem but shows the reason:

http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [upgrade], value: [h2,h2c]

It looks like your server is offering an upgrade to HTTP/2 even though the connection is already done with HTTP/2 - which makes no sense. Not only that, it is explicitly forbidden. From RFC 7540 section 8.1.2.2:

An endpoint MUST NOT generate an HTTP/2 message containing connection-specific header fields; any message containing connection-specific header fields MUST be treated as malformed (Section 8.1.2.6).... connection- specific header fields, such as Keep-Alive, Proxy-Connection, Transfer-Encoding, and Upgrade

It looks for me a bug since Apache should not send this header with HTTP/2.

My guess is that you have a configuration like this

Protocols h2 h2c http/1.1

Given that browsers do not support HTTP/2 without TLS anyway and that no Upgrade header is needed with HTTP/2 over TLS I recommend that you replace this configuration with

Protocols h2 http/1.1

This disables support for the unneeded HTTP/2 without TLS but should hopefully get rid of the Upgrade header this way since this is only needed for upgrading from plain HTTP to plain HTTP/2.

EDIT: according to the comment by the OP changing the Protocols configuration did not help. It was necessary to explicitly work around this behavior (i.e. bug) of mod_http2 by deleting the Upgrade header:

Header unset Upgrade
Steffen Ullrich
  • 12,227
  • 24
  • 37
  • 4
    Thank you! I indeed had the following config: `# Enable HTTP/2 by default # https://httpd.apache.org/docs/2.4/mod/core.html#protocols Protocols h2 h2c http/1.1 ` Following your recommendation and changing to `Protocols h2 http/1.1` did not remove the upgrade header, so instead I kept the Protocols line as is and added the following: `Header unset Upgrade` to remove the header. Can't say I'm 100% on top of what/why happens here but now it works fine in Safari too :-) – jola Oct 26 '18 at 07:12
  • @jola: thanks for the feedback. I've included it into the answer. – Steffen Ullrich Oct 26 '18 at 07:19
3

I think this is a Safari issue rather than an AWS / SSL issue. The search for that error gets many, many results on Google.

Everything checks out with the website according to the SSL Shopper test and SSL Labs Test.

I found this possible solution to the problem.

The solution was to go into Safari Preferences, under Privacy and list all Details. This provided a log of all sites where cookies, etc had been used. I found the Weather Network domain page and cleared all content from it. I was then able to reload the Weather Network page with no issues. I assume this would work for other similar singular sites.

There's also this which could be done with Apache.

Tim
  • 30,383
  • 6
  • 47
  • 77
  • Yes, I have googled this but not found anything that directly applies (afaiu). I've read the proposed solution for nginx but I'm not sure how/if this is applicable for apache. – jola Oct 25 '18 at 20:46
  • Apache will no doubt be able to delete the ["Upgrade" header](https://en.wikipedia.org/wiki/HTTP/1.1_Upgrade_header), which is all Nginx is doing. – Tim Oct 25 '18 at 21:23
0

Nginx: Header unset Upgrade; does not work if you proxy your request, use proxy_hide_header Upgrade; instead.

  • Thanks. Helped me out with my configuration Nginx and Apache. Without `proxy_hide_header Upgrade;` i could access `https://my.example.com/gallery/` with Chrome but not with `Safari` and not with `curl`. `curl -4 --http2 -I -v https://my.example.com/gallery/` reported `* http2 error: Invalid HTTP header field was received: frame type: 1, stream: 1, name: [upgrade], value: [h2,h2c] * HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)` but after setting `proxy_hide_header` it is working. –  Jan 16 '21 at 11:10
0

After I set following in Apache directives:

Header unset Upgrade

and following in NGinx directive:

proxy_hide_header Upgrade;

The problem with safari went away.