title: How to replace Nginx default error 400 "The plain HTTP request was sent to HTTPS port" page with Play! Framework backend.
body: <p>I have a website using Play! framework with multiple domains proxying to the backend, example.com and example.ca.</p>
  
  <p>I have all http requests on port 80 being rewritten to https on port 443. This is all working as expected.</p>
  
  <p>But when I type into the address bar <a href="http://example.com:443" rel="nofollow noreferrer">http://example.com:443</a>, I'm served nginx's default error page, which says</p>
  
  <pre><code>400 Bad Request
  The plain HTTP request was sent to HTTPS port
  nginx
  </code></pre>
  
  <p>I'd like to serve my own error page for this, but I just can't seem to get it working. Here's a snipped of my configuration.</p>
  
  <pre><code>upstream my-backend {
    server 127.0.0.1:9000;
  }
  
  server {
    listen                  443;
    ssl                     on;
  
    ssl_certificate        /etc/ssl/certs/example.crt;
    ssl_certificate_key    /etc/ssl/private/example.key;
    keepalive_timeout       70;
    server_name             example.com;
    add_header              Strict-Transport-Security max-age=15768000; #six months
  
  
    location / {
      proxy_pass              http://my-backend;
    }
  
    error_page 400 502 error.html;
    location = /error.html {
      root /usr/share/nginx/html;
    }
  
  
  
  }
  </code></pre>
  
  <p>It works when my Play! application is shut down, but when it's running it always serves up the default nginx page. </p>
  
  <p>I've tried adding the error page configuration to another server block  like this</p>
  
  <pre><code>server {
    listen 443;
    ssl off;
    server_name example.com;
  
    error_page [..]
  
  }
  </code></pre>
  
  <p>But that fails with the browser complaining about the certificate being wrong. </p>
  
  <p>I'd really ultimately like to be able to catch and handle any errors which aren't handled by my Play! application with a custom page, or pages. I'd also like this solution to work if the user manually enters the site's IP into the address bar instead of the server name. </p>
  
  <p>Any help is appreciated.</p>