Troubleshooting Apache ‘ssl_error_rx_record_too_long’ on CentOS Stream / Rocky Linux

Resolve Apache 'ssl_error_rx_record_too_long' browser error on CentOS Stream/Rocky Linux caused by SSL configuration mismatches on port 443.


Resolve Apache 'ssl_error_rx_record_too_long' browser error on CentOS Stream/Rocky Linux caused by SSL configuration mismatches on port 443.

Introduction

As a seasoned Systems Administrator, encountering the ssl_error_rx_record_too_long error when accessing an Apache web server via HTTPS can be perplexing. This client-side browser error, frequently seen in Firefox, indicates a fundamental miscommunication: the browser expects a TLS/SSL handshake on port 443 but receives data that doesn't conform to the SSL/TLS protocol, often plain HTTP. On CentOS Stream or Rocky Linux systems running Apache HTTPD, this usually points to an incorrect or incomplete SSL configuration for a VirtualHost designated for port 443. This guide will walk you through diagnosing and resolving this specific issue.

Symptom & Error Signature

When a user attempts to access your website over HTTPS (e.g., https://yourdomain.com), the browser will fail to establish a secure connection. Instead of loading the page, they will see an error message.

Typical Browser Error (Firefox):

Secure Connection Failed

An error occurred during a connection to yourdomain.com. Peer reports incompatible or
unsupported protocol version.

Error code: SSL_ERROR_RX_RECORD_TOO_LONG

Other browsers might display variations like:

  • Chrome/Edge: ERR_SSL_PROTOCOL_ERROR
  • Safari: "Safari can't establish a secure connection to the server."

Apache Error Logs (less common for this specific error, as it's often a config issue before actual Apache error processing): You might not see a direct ssl_error_rx_record_too_long message in Apache's logs, as the issue occurs during the initial SSL handshake. However, related errors like "SSL Library Error: -1" or "OpenSSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number" might appear if a partial handshake occurs or if the server attempts to process non-SSL data on an SSL port.

You might check /var/log/httpd/ssl_error_log or /var/log/httpd/error_log.

Root Cause Analysis

The ssl_error_rx_record_too_long error primarily signifies that the client (your browser) is sending an SSL/TLS handshake request to port 443, but the server is responding with something that is not an SSL/TLS record. The most common underlying reasons for this on an Apache server are:

  1. HTTP VirtualHost on an HTTPS Port: An Apache VirtualHost configured to serve plain HTTP content (without SSLEngine On and associated SSL directives) is mistakenly configured to listen on port 443, or it is the default VirtualHost that catches all traffic on port 443 due to a ServerName mismatch. When the browser initiates an HTTPS connection, Apache attempts to serve non-encrypted HTTP content, leading to the protocol mismatch.
  2. Missing or Incorrect SSLEngine On: The SSLEngine On directive, which tells Apache to enable SSL/TLS processing for a specific VirtualHost, is either missing from the VirtualHost definition for port 443 or is placed incorrectly.
  3. Incomplete SSL Configuration: While SSLEngine On might be present, critical directives like SSLCertificateFile and SSLCertificateKeyFile pointing to the correct certificate and key files are missing, malformed, or point to non-existent files. This prevents Apache from properly initializing the SSL context.
  4. Conflicting Listen Directives: Although less common for this specific error, if Apache is configured to listen on port 443 without any corresponding SSL-enabled VirtualHost, or if there's a conflict where a non-SSL VirtualHost *:443 takes precedence over an SSL one.
  5. Reverse Proxy Misconfiguration (less direct): If Apache is acting as a reverse proxy and is configured to proxy requests from HTTPS (client) to HTTP (backend) without proper SSLProxyEngine or mod_ssl handling, it could potentially lead to similar symptoms, though the direct error points more to Apache itself serving non-SSL data. For this guide, we assume Apache is the primary server.

The core problem is that Apache is accepting a connection on port 443 but then speaking HTTP, not HTTPS.

Step-by-Step Resolution

Follow these steps carefully to diagnose and resolve the ssl_error_rx_record_too_long error on your CentOS Stream / Rocky Linux Apache server.

1. Verify Apache is Listening on Port 443

First, ensure that Apache is actually listening for connections on port 443.

sudo ss -tuln | grep 443

You should see output similar to this, indicating httpd is listening:

tcp   LISTEN 0      128    *:443           *:*

If you don't see Apache listening on 443, you need to ensure Listen 443 https is present in your Apache configuration. This is typically in /etc/httpd/conf.d/ssl.conf or /etc/httpd/conf/httpd.conf.

2. Inspect Apache VirtualHost Configuration for Port 443

The most common culprit is an incorrect VirtualHost configuration. You need to identify the VirtualHost block handling port 443 for your domain.

Apache configuration files are typically found in:

  • /etc/httpd/conf/httpd.conf (main configuration)
  • /etc/httpd/conf.d/*.conf (modular configurations, preferred for VirtualHosts)
  • /etc/httpd/conf.modules.d/*.conf (module loading)

Start by examining ssl.conf and any domain-specific .conf files in /etc/httpd/conf.d/.

sudo grep -r "VirtualHost .*443" /etc/httpd/

This command will help you locate all VirtualHost definitions listening on port 443. Focus on the one relevant to your domain.

Let's assume you find a configuration file, e.g., /etc/httpd/conf.d/yourdomain-ssl.conf. Open it for editing:

sudo vi /etc/httpd/conf.d/yourdomain-ssl.conf

3. Ensure Proper SSL Directives in the VirtualHost

Inside your VirtualHost *:443 block, you must have the following directives:

  • SSLEngine On: Activates SSL/TLS processing.
  • SSLCertificateFile: Path to your SSL certificate.
  • SSLCertificateKeyFile: Path to your private key.
  • SSLCertificateChainFile or SSLCACertificateFile (optional but highly recommended): Path to your intermediate/chain certificate(s).

Correct Example Configuration:

<VirtualHost *:443>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    DocumentRoot /var/www/yourdomain.com/html

    # Enable SSL/TLS for this VirtualHost
    SSLEngine On

    # Paths to your SSL certificate, key, and chain files
    SSLCertificateFile /etc/pki/tls/certs/yourdomain.com.crt
    SSLCertificateKeyFile /etc/pki/tls/private/yourdomain.com.key
    SSLCertificateChainFile /etc/pki/tls/certs/yourdomain.com-chain.crt # Or SSLCACertificateFile

    # Recommended SSL Protocol and Cipher Suite settings (adjust as per security policy)
    SSLProtocol -all +TLSv1.2 +TLSv1.3
    SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
    SSLHonorCipherOrder on
    SSLSessionTickets Off
    SSLCompression Off

    # HSTS (HTTP Strict Transport Security) - Optional, but recommended for security
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"

    <Directory /var/www/yourdomain.com/html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog /var/log/httpd/yourdomain.com-ssl_error.log
    CustomLog /var/log/httpd/yourdomain.com-ssl_access.log combined
</VirtualHost>

Common issues to check:

  • SSLEngine On is missing: Add it.

  • Certificate/Key paths are incorrect: Double-check the exact paths.

  • Permissions on certificate/key files:

    • SSLCertificateFile and SSLCertificateChainFile should be readable by the Apache user (e.g., apache).
    • SSLCertificateKeyFile should be readable only by root and the Apache user. Permissions are critical; 600 for the key is common.
    sudo ls -l /etc/pki/tls/certs/yourdomain.com.crt
    sudo ls -l /etc/pki/tls/private/yourdomain.com.key
    # Example: Permissions for private key should be tight
    sudo chmod 600 /etc/pki/tls/private/yourdomain.com.key
    

Ensure that only your SSL-enabled VirtualHost is listening on port 443 for yourdomain.com. If you have another VirtualHost *:443 block that lacks SSLEngine On and is configured for HTTP, it could be unintentionally catching the traffic, especially if it's defined earlier in the configuration load order or has a matching ServerName.

4. Check for Conflicting VirtualHosts

Apache loads configuration files alphabetically. If you have multiple VirtualHost *:443 directives, the first one encountered that matches the incoming request might be used.

Carefully review all .conf files in /etc/httpd/conf.d/ for any VirtualHost *:443 directives that might be overriding your intended SSL configuration. Specifically, look for:

  • A VirtualHost *:443 block that doesn't have SSLEngine On.
  • A VirtualHost _default_:443 that might be catching all traffic.

If you find a duplicate or conflicting VirtualHost that should not be there, comment it out or remove it.

5. Verify mod_ssl is Enabled

Apache requires the mod_ssl module to handle SSL/TLS connections. On CentOS Stream / Rocky Linux, this module is usually installed and enabled by default when you install mod_ssl.

To confirm it's loaded, check /etc/httpd/conf.modules.d/00-ssl.conf and ensure the LoadModule ssl_module modules/mod_ssl.so line is uncommented.

sudo grep "ssl_module" /etc/httpd/conf.modules.d/00-ssl.conf

If it's not loaded, ensure the mod_ssl package is installed:

sudo dnf install mod_ssl

6. Test Apache Configuration and Restart

After making any changes to your Apache configuration, always test the configuration for syntax errors before restarting the service.

sudo apachectl configtest

You should see Syntax OK. If you see errors, review the output carefully to pinpoint the line and file where the error occurred and correct it.

Once Syntax OK is confirmed, restart Apache to apply the changes:

sudo systemctl restart httpd

If you have a firewall (e.g., firewalld) running, ensure that port 443 is open for incoming traffic.

sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

7. Clear Browser Cache and Test Again

Finally, clear your browser's cache and try accessing your website via HTTPS again. The ssl_error_rx_record_too_long error should now be resolved, and your site should load securely. If it persists, try an incognito/private browsing window or a different browser to rule out persistent caching issues.

By systematically verifying your Apache configuration, particularly the VirtualHost directives for port 443 and the presence and correctness of your SSL parameters, you can efficiently resolve the ssl_error_rx_record_too_long error.