Streamlit: reverse proxy + tls yields "Client sent an HTTP request to an HTTPS server"

1. The problem I’m having:

I am running running Caddy to provide a reverse proxy to a streamlit service. The service runs on a VPS with a FQD of myexample.com but streamlit has a bind address 127.0.0.1, i.e. it is not reachable from outside, because I would like to add SSL through Caddy.

Unfortunately, I am getting a series of errors when trying to connect to it through Caddy:

See below for the detailed error logs.

2. Error messages and/or full log output:

1st error

curl -vL https://myexample.com                                                                                                                 
*   Trying x.x.x.x:443...
* Connected to myexample.com (x.x.x.x) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=myexample.com
*  start date: Apr 10 20:31:59 2024 GMT
*  expire date: Jul  9 20:31:58 2024 GMT
*  subjectAltName: host "myexample.com" matched cert's "myexample.com"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://myexample.com/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: myexample.com]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.4.0]
* [HTTP/2] [1] [accept: */*]
> GET / HTTP/2
> Host: myexample.com
> User-Agent: curl/8.4.0
> Accept: */*
> 
< HTTP/2 400 
< alt-svc: h3=":443"; ma=2592000
< server: Caddy
< content-type: text/plain; charset=utf-8
< date: Fri, 03 May 2024 19:53:59 GMT
< 
Client sent an HTTP request to an HTTPS server.
* Connection #0 to host myexample.com left intact

2nd error

curl -vL myexample.com
*   Trying x.x.x.x:80...
* Connected to myexample.com (x.x.x.x) port 80
> GET / HTTP/1.1
> Host: myexample.com
> User-Agent: curl/8.4.0
> Accept: */*
> 
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://myexample.com:0/
< Server: Caddy
< Date: Fri, 03 May 2024 20:00:56 GMT
< Content-Length: 0
< 
* Closing connection
* Clear auth, redirects to port from 80 to 0
* Issue another request to this URL: 'https://myexample.com:0/'
*   Trying x.x.x.x:0...
* Immediate connect fail for x.x.x.x: Can't assign requested address
* Failed to connect to myexample.com port 0 after 2 ms: Couldn't connect to server
* Closing connection
curl: (7) Failed to connect to myexample.com port 0 after 2 ms: Couldn't connect to server

3. Caddy version:

v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

4. How I installed and ran Caddy:

Debian package

a. System environment:

Debian 6.1.76-1 (2024-02-01) x86_64 GNU/Linux

b. Command:

sudo systemctl reload caddy

c. Service/unit/compose file:

standard file of Debian installation (no change)

d. My complete Caddy config:

myexample.com {
        tls ssl@myexample.com
        reverse_proxy 127.0.0.1:8501
}

What’s in your Caddy logs? Enable the debug global option and make those two requests again and show the logs.

The recommended command for reading your logs is at Keep Caddy Running — Caddy Documentation

Thanks for the response. Below is the log entry that leads to “Client sent an HTTP request to an HTTPS server”. I replaced the IP of my VPS with x.x.x.x, while leaving the other IP (114.34.185.7)

May 04 10:05:57 caddy[402877]: {"level":"debug","ts":1714809957.0013316,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"114.34.185.7","remote_port":"46354","server_name":"","remote":"114.34.185.7:46354","identifier":"x.x.x.x","cipher_suites":[52393,52392,49195,49199,49196,49200,49161,49171,49162,49172,156,157,47,53,49170,10,4867,4865,4866],"cert_cache_fill":0.0002,"load_or_obtain_if_necessary":true,"on_demand":false}
May 04 10:05:57 caddy[402877]: {"level":"debug","ts":1714809957.0014262,"logger":"http.stdlib","msg":"http: TLS handshake error from 114.34.185.7:46354: no certificate available for 'x.x.x.x'"}

I’m confused. I feel like we’re missing information here. It doesn’t help that you’re obfuscating information, it only makes it harder for us to help.

How did you make the request? This probably means the client didn’t send TLS-SNI (i.e. a valid domain in the TLS handshake). But you redacted it, so :man_shrugging:

Are you sure your proxy upstream (i.e. 127.0.0.1:8501) is an HTTP server?

1 Like