# SSL_ERROR_RX_RECORD_TOO_LONG: port 443 is not speaking TLS

> Firefox shows SSL_ERROR_RX_RECORD_TOO_LONG when the server answers HTTPS with plain HTTP. Usually listen 443 without ssl, or HTTPS sent to an HTTP port.

Source: https://ssl.sh/errors/ssl-error-rx-record-too-long/
Last updated: 2026-11-10

**SSL_ERROR_RX_RECORD_TOO_LONG means Firefox sent a TLS handshake and got back something that is not TLS, almost always a plain HTTP response.** The first bytes of "HTTP/1.1 400 Bad Request" decode as a TLS record with an enormous length, hence the odd name. The fix is on the server: make the port speak TLS.

## Is it the site or your device?

Almost always the site. Confirm with the [SSL checker](https://ssl.sh/tools/ssl-checker/):

```bash
curl ssl.sh/example.com
```

If the checker reports that the port does not speak TLS, the server must be fixed. On the visitor side, check that you are not adding `https://` to a port that is meant for plain HTTP, and that no proxy configured in Firefox answers on behalf of the site.

## Causes

### 1. Nginx: listen 443 without ssl

This is the classic mistake: Nginx serves plain HTTP on port 443 if the `ssl` parameter is missing:

```nginx
listen 443;        # wrong: plain HTTP on 443
listen 443 ssl;    # right
```

Confirm by sending plain HTTP to port 443:

```bash
curl -s -o /dev/null -w "%{http_code}\n" http://example.com:443/
```

If that returns an HTTP status code, the port is not using TLS.

### 2. Apache: SSLEngine off or mod_ssl missing

The `*:443` virtual host exists, but `SSLEngine on` is missing or mod_ssl is not loaded. Run `apachectl -M | grep ssl` to check.

### 3. HTTPS sent to an HTTP-only port

Links or bookmarks like `https://example.com:8080/` reach an application server that only speaks HTTP. Either use `http://` for that port or put TLS in front of it.

### 4. Load balancer or CDN forwarding to the wrong port

A TCP-mode load balancer passes HTTPS straight through to a backend port that expects HTTP, or a CDN is set to fetch from the origin with HTTPS on port 80. Align the protocol and port.

### 5. Proxy configured in the browser

A local or corporate HTTP proxy that cannot handle `CONNECT` properly may answer HTTPS with an HTTP error. Test without the proxy.

## What it looks like in each browser

| Browser | What you see |
|---|---|
| Firefox | "Secure Connection Failed" with `SSL_ERROR_RX_RECORD_TOO_LONG` |
| Chrome / Edge | [ERR_SSL_PROTOCOL_ERROR](https://ssl.sh/errors/err-ssl-protocol-error/), "example.com sent an invalid response" |
| Safari | [Safari can't establish a secure connection](https://ssl.sh/errors/safari-cant-establish-secure-connection/) |
| curl / OpenSSL | `wrong version number` or `packet length too long` |

## How site owners fix it

Enabling TLS on every port 443 listener fixes it.

**1. Enable TLS on the listener.** Nginx:

```nginx
server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate     /etc/nginx/ssl/example.com.fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
}
```

Apache:

```apache
<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile    /etc/ssl/example.com.fullchain.pem
    SSLCertificateKeyFile /etc/ssl/example.com.key
</VirtualHost>
```

**2. Check every listen socket on port 443**, including IPv6 (`[::]:443`) and IP-specific lines such as `203.0.113.10:443`. Each distinct address needs `ssl`; a socket where no server block sets it serves plain HTTP. `nginx -T | grep -n "listen"` lists them all.

**3. Reload and verify.** `nginx -t && systemctl reload nginx`, then `curl ssl.sh/example.com` should show a completed TLS handshake.
