Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to deploy a website with only https access, no http access. I'm sure that I'm just missing some simple line in a configuration file.

As the title says, it's Sinatra 0.9.4 on nginx 0.7.65 through passenger 2.2.9.

The main ruby file for the Sinatra service has:

require 'ssl_requirement'

def ssl_required?
end has (although I'm not sure it's relevant):

require 'rubygems'
require 'sinatra'
require 'app.rb'

set :environment, :production
run Sinatra::Application

The nginx.conf file looks like:

 worker_processes  1;

 events {
   worker_connections  1024;

 http {
   passenger_root /var/lib/gems/1.8/gems/passenger-2.2.9;
   passenger_ruby /usr/bin/ruby1.8;

   include       mime.types;
   default_type  application/octet-stream;

   # HTTPS server
   server {
     listen       80;
     listen       443;
     server_name  an.internal.ip.address;
     root         /my/app/dir/public;
     passenger_enabled on;

     proxy_set_header X_FORWARDED_PROTO https;

     ssl                  on;
     ssl_certificate      /my/app/dir/certificate.pem;
     ssl_certificate_key      /my/app/dir/privkey.pem;

     ssl_session_timeout  5m;

     ssl_protocols  SSLv2 SSLv3 TLSv1;
     ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
     ssl_prefer_server_ciphers   on;



Instead of redirecting all http requests to https, I instead get the error:

The plain HTTP request was sent to HTTPS port

How can I fix this? https requests to https://an.internal.ip.address work fine.

(it also happens with nginx-0.6.36, for what that's worth).

Not sure if this should get tagged with Sinatra, but I don't have enough rep for that yet.

share|improve this question
up vote 1 down vote accepted

if you type in http://server/ the browser sends plain text request to the server on port 80. whereas if you type in https://server/ it'll send encrypted request to port 443. what you're doing is you sending plain text to https, so webserver expects encrypted, but gets plain.

it'd work if you did https://server:80/, so webrowser knows it needs to encrypt, but sends to 80. i doub't you can expect that from users.

what you want to is, accept unencrypted traffic on 80, and just http redirect all requests to 443. in nginx:

server {
  listen server_ip:80;
  server_name server_name;
  location / {
    rewrite ^/(.*) https://server_name permanent;
share|improve this answer
Muchas gracias, works like a charm! – mmr Feb 9 '10 at 7:31

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.