Issue
You're getting 495 Certificate Error
HTTP status code responses for requests you're proxying via a reverse proxy like Nginx. This isn't generating any logs in your application and you're unsure why it's happening.
Resolution
This error code is thrown when there's an SNI hostname mismatch. What that means is the request being routed has a Host
header with a different domain than the server name that's indicated on the certificate. This can happen if you're taking requests at one domain and then proxying them to another domain that's using Heroku SSL without rewriting the Host
header to match the second domain.
This can happen using any reverse proxy, but for clarity's sake we'll use Nginx to demonstrate the issue. Imagine you're accepting requests at www.example.com
, but proxying all requests to /foobar
to a Heroku application listening at foobar.example.com
. You might have a location block that looks something like this:
set $foobar_backend foobar.example.com;
location /foobar {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_ssl_server_name on;
proxy_ssl_name foobar.example.com;
proxy_ssl_protocols TLSv1.2;
proxy_pass https://$foobar_backend;
proxy_read_timeout 90;
}
The critical error in the above is that the Host
header is being set to $host
. This just passes the original hostname through as is. Instead, it should be rewriting the Host
header to foobar.example.com
.