Server only speaks HTTP, not TLS

1. The problem I’m having:

I’m trying to setup a reverse proxy for my home server, but I cannot get the SSL to work.

  • Port 80 and 443 is both forwarded to the machine which is running Caddy.
  • DNS is correctly resolved, pointing to my ip address.

2. Error messages and/or full log output:

I get an error stating "91.93.203.117: Server only speaks HTTP, not TLS.

3. Caddy version:

I am using v2.7.6

4. How I installed and ran Caddy:

Followed the instructions on the official site.

a. System environment:

Tried both on Ubuntu Server and CentOS9. Same error.

b. Command:

sudo caddy run

d. My complete Caddy config:

Default config with :80 replaced with my domain. I’ve also added my email as well.

{
        email user@example.com
}

rottenking.com {
        root * /usr/share/caddy
        file_server
}

Where do you see this error? That’s not something Caddy would emit.

Please elaborate. There’s a lot of details missing here. Show your Caddy logs, show an example request with curl -v.

If you installed Caddy using a package manager, you shouldn’t run caddy run directly. You should be using the systemd service. See the docs:

Apologies for the missing log. Connecting the site like this shows ‘This site can’t provide a secure connection’ (ERR_SSL_PROTOCOL_ERROR)

2024/02/07 08:04:16.003	INFO	using adjacent Caddyfile
2024/02/07 08:04:16.005	INFO	admin	admin endpoint started	{"address": "localhost:2019", "enforce_origin": false, "origins": ["//localhost:2019", "//[::1]:2019", "//127.0.0.1:2019"]}
2024/02/07 08:04:16.005	INFO	http.auto_https	server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS	{"server_name": "srv0", "https_port": 443}
2024/02/07 08:04:16.005	INFO	http.auto_https	enabling automatic HTTP->HTTPS redirects	{"server_name": "srv0"}
2024/02/07 08:04:16.005	INFO	tls.cache.maintenance	started background certificate maintenance	{"cache": "0xc0001f3300"}
2024/02/07 08:04:16.005	DEBUG	http.auto_https	adjusted config	{"tls": {"automation":{"policies":[{"subjects":["rottenking.com"]},{}]}}, "http": {"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"vars","root":"/usr/share/caddy"},{"handler":"file_server","hide":["./Caddyfile"]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
2024/02/07 08:04:16.005	INFO	http	enabling HTTP/3 listener	{"addr": ":443"}
2024/02/07 08:04:16.005	DEBUG	http	starting server loop	{"address": "[::]:443", "tls": true, "http3": true}
2024/02/07 08:04:16.005	INFO	http.log	server running	{"name": "srv0", "protocols": ["h1", "h2", "h3"]}
2024/02/07 08:04:16.005	DEBUG	http	starting server loop	{"address": "[::]:80", "tls": false, "http3": false}
2024/02/07 08:04:16.005	INFO	http.log	server running	{"name": "remaining_auto_https_redirects", "protocols": ["h1", "h2", "h3"]}
2024/02/07 08:04:16.005	INFO	http	enabling automatic TLS certificate management	{"domains": ["rottenking.com"]}
2024/02/07 08:04:16.006	INFO	autosaved config (load with --resume flag)	{"file": "/root/.config/caddy/autosave.json"}
2024/02/07 08:04:16.006	INFO	serving initial configuration
2024/02/07 08:04:16.006	INFO	tls.obtain	acquiring lock	{"identifier": "rottenking.com"}
2024/02/07 08:04:16.022	WARN	tls	storage cleaning happened too recently; skipping for now	{"storage": "FileStorage:/root/.local/share/caddy", "instance": "1acb5a82-8583-4396-88ab-136d56b455f0", "try_again": "2024/02/08 08:04:16.022", "try_again_in": 86399.999999679}
2024/02/07 08:04:16.022	INFO	tls.obtain	lock acquired	{"identifier": "rottenking.com"}
2024/02/07 08:04:16.022	INFO	tls	finished cleaning storage units
2024/02/07 08:04:16.022	INFO	tls.obtain	obtaining certificate	{"identifier": "rottenking.com"}
2024/02/07 08:04:16.022	DEBUG	events	event	{"name": "cert_obtaining", "id": "3beb2066-2b49-45b1-9c2d-5c60629b19c5", "origin": "tls", "data": {"identifier":"rottenking.com"}}
2024/02/07 08:04:16.022	DEBUG	tls.obtain	trying issuer 1/2	{"issuer": "acme-v02.api.letsencrypt.org-directory"}
2024/02/07 08:04:16.023	INFO	tls.issuance.acme	waiting on internal rate limiter	{"identifiers": ["rottenking.com"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": "yigit.eren@rottenking.com"}
2024/02/07 08:04:16.023	INFO	tls.issuance.acme	done waiting on internal rate limiter	{"identifiers": ["rottenking.com"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": "yigit.eren@rottenking.com"}
2024/02/07 08:04:16.804	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "GET", "url": "https://acme-v02.api.letsencrypt.org/directory", "headers": {"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["752"],"Content-Type":["application/json"],"Date":["Wed, 07 Feb 2024 08:04:16 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/02/07 08:04:17.015	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "HEAD", "url": "https://acme-v02.api.letsencrypt.org/acme/new-nonce", "headers": {"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Date":["Wed, 07 Feb 2024 08:04:16 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["2ksh1KUsyF17Qaxn-lCkVNAhspIpXEqD64xbGCrfs4YZIlk8C94"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/02/07 08:04:17.261	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/new-order", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["1557397327"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["340"],"Content-Type":["application/json"],"Date":["Wed, 07 Feb 2024 08:04:17 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/1557397327/242538555107"],"Replay-Nonce":["2ksh1KUspuhznowTYXuCRWfUDKM0-JbCX8cNy2Rx4XIOW7nm6QE"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 201}
2024/02/07 08:04:17.476	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/authz-v3/312542659847", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["1557397327"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["798"],"Content-Type":["application/json"],"Date":["Wed, 07 Feb 2024 08:04:17 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["kRyagOpUjvq5hIc_Murn9uJ131oi1qTjlGoYDZnBwsPdhWtXaYU"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/02/07 08:04:17.476	INFO	tls.issuance.acme.acme_client	trying to solve challenge	{"identifier": "rottenking.com", "challenge_type": "tls-alpn-01", "ca": "https://acme-v02.api.letsencrypt.org/directory"}
2024/02/07 08:04:17.476	DEBUG	tls.issuance.acme.acme_client	waiting for solver before continuing	{"identifier": "rottenking.com", "challenge_type": "tls-alpn-01"}
2024/02/07 08:04:17.476	DEBUG	http.stdlib	http: TLS handshake error from 127.0.0.1:46238: EOF
2024/02/07 08:04:17.476	DEBUG	tls.issuance.acme.acme_client	done waiting for solver	{"identifier": "rottenking.com", "challenge_type": "tls-alpn-01"}
2024/02/07 08:04:17.696	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/chall-v3/312542659847/GQRknw", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["1557397327"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["191"],"Content-Type":["application/json"],"Date":["Wed, 07 Feb 2024 08:04:17 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\"","<https://acme-v02.api.letsencrypt.org/acme/authz-v3/312542659847>;rel=\"up\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/chall-v3/312542659847/GQRknw"],"Replay-Nonce":["2ksh1KUs6tZtnoPEtlHg0cWY359bWheXPpCgK2KBCcAzYUPKDns"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/02/07 08:04:17.696	DEBUG	tls.issuance.acme.acme_client	challenge accepted	{"identifier": "rottenking.com", "challenge_type": "tls-alpn-01"}
2024/02/07 08:04:18.160	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/authz-v3/312542659847", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["1557397327"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["798"],"Content-Type":["application/json"],"Date":["Wed, 07 Feb 2024 08:04:18 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["kRyagOpU6uXUigA9Hs2m-ab3D0dTmPoKsSpYrnjiGaLysWaWrRk"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/02/07 08:04:18.631	DEBUG	tls.issuance.acme.acme_client	http request	{"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/authz-v3/312542659847", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Boulder-Requester":["1557397327"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["826"],"Content-Type":["application/json"],"Date":["Wed, 07 Feb 2024 08:04:18 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["kRyagOpUcjYtmyj7HlEkqXLz0QH4C02op5xQZi6SRj7m-7LUF1s"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2024/02/07 08:04:18.631	ERROR	tls.issuance.acme.acme_client	challenge failed	{"identifier": "rottenking.com", "challenge_type": "tls-alpn-01", "problem": {"type": "urn:ietf:params:acme:error:malformed", "title": "", "detail": "91.93.203.117: Server only speaks HTTP, not TLS", "instance": "", "subproblems": []}}
2024/02/07 08:04:18.631	ERROR	tls.issuance.acme.acme_client	validating authorization	{"identifier": "rottenking.com", "problem": {"type": "urn:ietf:params:acme:error:malformed", "title": "", "detail": "91.93.203.117: Server only speaks HTTP, not TLS", "instance": "", "subproblems": []}, "order": "https://acme-v02.api.letsencrypt.org/acme/order/1557397327/242538555107", "attempt": 1, "max_attempts": 3}
2024/02/07 08:04:18.631	ERROR	tls.obtain	could not get certificate from issuer	{"identifier": "rottenking.com", "issuer": "acme-v02.api.letsencrypt.org-directory", "error": "HTTP 400 urn:ietf:params:acme:error:malformed - 91.93.203.117: Server only speaks HTTP, not TLS"}
2024/02/07 08:04:18.631	DEBUG	tls.obtain	trying issuer 2/2	{"issuer": "acme.zerossl.com-v2-DV90"}
2024/02/07 08:04:18.631	INFO	tls.issuance.zerossl	waiting on internal rate limiter	{"identifiers": ["rottenking.com"], "ca": "https://acme.zerossl.com/v2/DV90", "account": "yigit.eren@rottenking.com"}
2024/02/07 08:04:18.631	INFO	tls.issuance.zerossl	done waiting on internal rate limiter	{"identifiers": ["rottenking.com"], "ca": "https://acme.zerossl.com/v2/DV90", "account": "yigit.eren@rottenking.com"}
2024/02/07 08:04:18.983	DEBUG	tls.issuance.zerossl.acme_client	http request	{"method": "GET", "url": "https://acme.zerossl.com/v2/DV90", "headers": {"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Access-Control-Allow-Origin":["*"],"Content-Length":["645"],"Content-Type":["application/json"],"Date":["Wed, 07 Feb 2024 08:04:18 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]}, "status_code": 200}
2024/02/07 08:04:19.183	DEBUG	tls.issuance.zerossl.acme_client	http request	{"method": "HEAD", "url": "https://acme.zerossl.com/v2/DV90/newNonce", "headers": {"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Type":["application/octet-stream"],"Date":["Wed, 07 Feb 2024 08:04:19 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["VWX94OHrSUVcxkY1XTZHA_z6bq2MY-p6kcv_rDoKEhE"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]}, "status_code": 200}
2024/02/07 08:04:19.522	DEBUG	tls.issuance.zerossl.acme_client	http request	{"method": "POST", "url": "https://acme.zerossl.com/v2/DV90/newOrder", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["276"],"Content-Type":["application/json"],"Date":["Wed, 07 Feb 2024 08:04:19 GMT"],"Location":["https://acme.zerossl.com/v2/DV90/order/ubqAnl6RqvIK2pxrn0qJ-w"],"Replay-Nonce":["NzLNmuIsuRqSuWMOabj8QLgcfPewsZb8fYPEDT83hLQ"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]}, "status_code": 201}
2024/02/07 08:04:19.715	DEBUG	tls.issuance.zerossl.acme_client	http request	{"method": "POST", "url": "https://acme.zerossl.com/v2/DV90/authz/IzNuzWcyNkKL8fDwOSVgiA", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.7.6 CertMagic acmez (linux; amd64)"]}, "response_headers": {"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["294"],"Content-Type":["application/json"],"Date":["Wed, 07 Feb 2024 08:04:19 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["8xmZwkfesAU5RkoIsmR8fkkDVbKFYRFzkjNJHHlhr_I"],"Retry-After":["86400"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]}, "status_code": 200}
2024/02/07 08:04:19.715	ERROR	tls.obtain	could not get certificate from issuer	{"identifier": "rottenking.com", "issuer": "acme.zerossl.com-v2-DV90", "error": "[rottenking.com] solving challenges: authz https://acme.zerossl.com/v2/DV90/authz/IzNuzWcyNkKL8fDwOSVgiA has unexpected status; order will fail: invalid (order=https://acme.zerossl.com/v2/DV90/order/ubqAnl6RqvIK2pxrn0qJ-w) (ca=https://acme.zerossl.com/v2/DV90)"}
2024/02/07 08:04:19.715	DEBUG	events	event	{"name": "cert_failed", "id": "f8a0a382-941d-4e38-9581-34e9f9c1fdb5", "origin": "tls", "data": {"error":{},"identifier":"rottenking.com","issuers":["acme-v02.api.letsencrypt.org-directory","acme.zerossl.com-v2-DV90"],"renewal":false}}
2024/02/07 08:04:19.715	ERROR	tls.obtain	will retry	{"error": "[rottenking.com] Obtain: [rottenking.com] solving challenges: authz https://acme.zerossl.com/v2/DV90/authz/IzNuzWcyNkKL8fDwOSVgiA has unexpected status; order will fail: invalid (order=https://acme.zerossl.com/v2/DV90/order/ubqAnl6RqvIK2pxrn0qJ-w) (ca=https://acme.zerossl.com/v2/DV90)", "attempt": 1, "retrying_in": 60, "elapsed": 3.692983283, "max_duration": 2592000}
^C2024/02/07 08:04:21.816	INFO	shutting down	{"signal": "SIGINT"}
2024/02/07 08:04:21.816	WARN	exiting; byeee!! 👋	{"signal": "SIGINT"}
2024/02/07 08:04:21.816	INFO	http	servers shutting down with eternal grace period
2024/02/07 08:04:21.816	INFO	tls.obtain	releasing lock	{"identifier": "rottenking.com"}
2024/02/07 08:04:21.817	ERROR	tls.obtain	unable to unlock	{"identifier": "rottenking.com", "lock_key": "issue_cert_rottenking.com", "error": "remove /root/.local/share/caddy/locks/issue_cert_rottenking.com.lock: no such file or directory"}
2024/02/07 08:04:21.817	ERROR	tls	job failed	{"error": "rottenking.com: obtaining certificate: context canceled"}
2024/02/07 08:04:21.817	INFO	admin	stopped previous server	{"address": "localhost:2019"}
2024/02/07 08:04:21.817	INFO	shutdown complete	{"signal": "SIGINT", "exit_code": 0}```

Weird.

Are you port forwarding connections from port 443 → 80? You should not do that. You should port forward 443 → 443, and 80 → 80.

I have my ports setup like this. I don’t think there is any mistake here. I’ll try explicitly setting the external port numbers as well.

Edit: Seems like explicitly setting the external port numbers worked. We can call it a router problem I guess!