Troubleshooting Apache: ‘ssl_error_rx_record_too_long’ on macOS Local Environment (Port 443 Mismatch)
Resolve Apache 'ssl_error_rx_record_too_long' on macOS for local development. Fix SSL port 443 mismatches and certificate configuration. For experts.
Resolve Apache 'ssl_error_rx_record_too_long' on macOS for local development. Fix SSL port 443 mismatches and certificate configuration. For experts.
Welcome, fellow SysAdmins and DevOps engineers. Encountering ssl_error_rx_record_too_long specifically when setting up a local Apache web server with SSL on macOS can be a perplexing issue. This error typically signifies a fundamental protocol mismatch: your browser is attempting an HTTPS (SSL/TLS) handshake, but the server responding on port 443 is either not configured for SSL, is serving plain HTTP, or is a completely different service. This guide will meticulously walk you through diagnosing and resolving this common local development hurdle.
Symptom & Error Signature
When attempting to access your local development site via https://localhost or https://yourdomain.local, your web browser will present a security error page, often similar to the following:
Firefox:
Secure Connection Failed
An error occurred during a connection to yourdomain.local. SSL received a record that exceeded the maximum permissible length.
Error code: SSL_ERROR_RX_RECORD_TOO_LONG
The page you are trying to view cannot be shown because the authenticity of the received data could not be verified.
Please contact the website owners to inform them of this problem.
Chrome/Safari:
This site can't provide a secure connection
yourdomain.local sent an invalid response.
ERR_SSL_PROTOCOL_ERROR
From the command line, using curl -v https://yourdomain.local will often reveal the underlying issue by attempting an SSL handshake, receiving a non-SSL response, and failing:
# Example curl output attempting to connect to a non-SSL endpoint on port 443
$ curl -v https://localhost:443
* Trying 127.0.0.1:443...
* Connected to localhost (127.0.0.1) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* Recv failure: Connection reset by peer
* OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:443
* Closing connection 0
curl: (35) Recv failure: Connection reset by peer
(Note: SSL_ERROR_SYSCALL can be a proxy for SSL_ERROR_RX_RECORD_TOO_LONG when the underlying TCP connection is severed due to an invalid initial response.)
A more telling curl command to definitively check what's actually on port 443 is:
curl -v http://localhost:443
If this command successfully returns HTTP headers and content, it unequivocally confirms that an HTTP server is listening on port 443, which is the root cause of the ssl_error_rx_record_too_long when accessed via HTTPS.
Root Cause Analysis
The ssl_error_rx_record_too_long error on port 443 typically stems from one or more of these fundamental misconfigurations in an Apache HTTP Server environment on macOS:
- Protocol Mismatch: The most common cause. Your browser initiates an SSL/TLS handshake expecting a secure connection, but the service listening on port 443 is configured to serve plain HTTP. The server responds with an HTTP header (e.g.,
HTTP/1.1 200 OK) instead of an SSL/TLS handshake record, which the SSL client interprets as an invalid, excessively long record. mod_sslNot Loaded: The Apache SSL module (mod_ssl.so) is not enabled in yourhttpd.confor a related configuration file. Without this module, Apache cannot handle SSL/TLS connections.httpd-ssl.confNot Included: The primary SSL configuration file (oftenhttpd-ssl.confor a similar name) where your SSL VirtualHost directives reside is not included by the mainhttpd.conf.- Incorrect SSL VirtualHost Configuration:
- The
<VirtualHost *:443>or<VirtualHost yourdomain.local:443>block is missing or misconfigured. SSLEngine Onis not present within the SSL VirtualHost.SSLCertificateFileandSSLCertificateKeyFiledirectives point to incorrect, non-existent, or permission-restricted certificate/key files.
- The
- Another Process on Port 443: Another web server (e.g., Nginx, a different Apache instance like system Apache vs. Homebrew Apache, MAMP/XAMPP, Docker containers) or an unrelated service is already bound to port 443, preventing your intended Apache instance from listening correctly, or providing the incorrect protocol response.
- Apache
ListenDirective Misconfiguration: Apache is not configured to listen on port 443 at all, or it's listening on the wrong IP address. - Conflicting Apache Instances (macOS Specific): macOS ships with a pre-installed Apache. If you're using Homebrew to install a separate Apache instance, conflicts can arise if both are attempting to bind to the same ports (80, 443).
Step-by-Step Resolution
Follow these steps systematically to diagnose and rectify the ssl_error_rx_record_too_long error.
1. Verify Port 443 Usage and Active Apache Instance
First, confirm what process, if any, is currently listening on port 443. This is crucial for identifying conflicts.
On macOS:
# Check for processes listening on port 443
sudo lsof -i TCP:443 | grep LISTEN
# or
sudo netstat -anv | grep 443 | grep LISTEN
The output will show the process ID (PID) and the command. Look for httpd or nginx. If no process is listed, Apache isn't even trying to listen on 443, or it failed to start. If an unexpected process is listed, you've found a conflict.
Next, identify which Apache instance is potentially running.
On macOS (Homebrew Apache):
brew services list | grep httpd
Expected output if running: httpd started root /usr/local/opt/httpd/bin/httpd -D FOREGROUND
On macOS (System Apache):
sudo apachectl status
If Apache is running, this will show its status.
If you find two Apache instances (e.g., Homebrew and System Apache) or another web server like Nginx attempting to listen on port 443, you must stop the conflicting process. Only one service can bind to a port at a time.
To stop Homebrew Apache:
brew services stop httpd
To stop macOS System Apache:
sudo apachectl stop
2. Inspect Apache Main Configuration (httpd.conf)
The primary configuration file dictates which modules Apache loads and which other configuration files it includes. The typical location for Homebrew Apache is /usr/local/etc/httpd/httpd.conf and for System Apache, /etc/apache2/httpd.conf.
Open your httpd.conf with a text editor (e.g., nano, vim, code):
# For Homebrew Apache
sudo nano /usr/local/etc/httpd/httpd.conf
# For System Apache (might need sudo)
sudo nano /etc/apache2/httpd.conf
Verify the following directives:
Load
mod_sslmodule: Ensure the line formod_ssl.sois uncommented.LoadModule ssl_module libexec/mod_ssl.so(The exact path
libexec/mod_ssl.somight vary based on your Apache installation. For Homebrew, it's usually correct.)Listen on Port 443: Ensure Apache is configured to listen on the SSL port.
Listen 443Include SSL Configuration File: Confirm that your main SSL configuration file is included. This file typically contains your SSL VirtualHost.
Include /usr/local/etc/httpd/extra/httpd-ssl.conf(Adjust path as necessary for your setup. For System Apache, it's often
/etc/apache2/extra/httpd-ssl.confor similar.)
After making any changes, save the file.
3. Configure SSL VirtualHost (httpd-ssl.conf)
This file defines how Apache handles SSL connections for your domains. The typical location for Homebrew Apache is /usr/local/etc/httpd/extra/httpd-ssl.conf.
Open httpd-ssl.conf:
# For Homebrew Apache
sudo nano /usr/local/etc/httpd/extra/httpd-ssl.conf
# For System Apache
sudo nano /etc/apache2/extra/httpd-ssl.conf
Inside this file, locate or create a <VirtualHost> block for port 443. It should look similar to this (adjust yourdomain.local and paths for your setup):
#
# SSL Virtual Host Context
#
<VirtualHost _default_:443> # Or <VirtualHost yourdomain.local:443>
DocumentRoot "/Users/youruser/Sites/yourdomain.local/public"
ServerName yourdomain.local:443
ServerAdmin [email protected]
ErrorLog "/usr/local/var/log/httpd/yourdomain.local-ssl_error_log"
TransferLog "/usr/local/var/log/httpd/yourdomain.local-ssl_access_log"
SSLEngine on
SSLProxyEngine on # If using as a reverse proxy
SSLProtocol all -SSLv2 -SSLv3 # Good security practice
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH # Good security practice
SSLCertificateFile "/usr/local/etc/httpd/ssl/yourdomain.local.crt"
SSLCertificateKeyFile "/usr/local/etc/httpd/ssl/yourdomain.local.key"
# SSLCertificateChainFile "/path/to/your/ca-bundle.crt" # If you have one
<Directory "/Users/youruser/Sites/yourdomain.local/public">
Options FollowSymLinks Indexes
AllowOverride All
Require all granted
</Directory>
# Other configurations like ProxyPass, RewriteRules etc.
# ...
</VirtualHost>
Key directives to verify:
<VirtualHost _default_:443>oryourdomain.local:443: Ensures this block handles connections on port 443.SSLEngine on: Absolutely critical. This enables SSL/TLS for this VirtualHost. If this is missing oroff, you'll get thessl_error_rx_record_too_longerror.SSLCertificateFile: Path to your SSL certificate (e.g., a self-signed.crtfile for local dev).SSLCertificateKeyFile: Path to your private key file (.key).
Ensure that your certificate (
.crt) and private key (.key) files exist at the specified paths and have correct permissions. The private key (.key) should typically be readable only by therootor Apache user. Common permissions are644for.crtand600for.key. Incorrect paths or permissions will prevent SSL from working.
If you don't have self-signed certificates, you can generate them for local development using openssl:
# Create a directory for SSL certificates if it doesn't exist
sudo mkdir -p /usr/local/etc/httpd/ssl
cd /usr/local/etc/httpd/ssl
# Generate a self-signed certificate and key
# Common Name (CN) should match your ServerName (e.g., yourdomain.local)
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout yourdomain.local.key -out yourdomain.local.crt
Follow the prompts, entering yourdomain.local for "Common Name". Remember to import yourdomain.local.crt into your macOS Keychain and mark it as trusted for full browser trust in local development.
4. Validate Configuration and Restart Apache
After making any configuration changes, always validate Apache's configuration syntax before restarting to prevent service outages.
Validate configuration:
# On macOS (Homebrew Apache)
sudo apachectl configtest
# On macOS (System Apache) or general Apache
sudo apachectl -t
# On Ubuntu/Debian with Apache2
sudo apache2ctl configtest
You should see Syntax OK. If not, review the error messages and fix the issues in your httpd.conf or httpd-ssl.conf.
Never restart Apache without first running
configtest. A syntax error can prevent Apache from starting, leading to downtime.
Restart Apache:
# On macOS (Homebrew Apache)
brew services restart httpd
# On macOS (System Apache)
sudo apachectl restart
# On Ubuntu/Debian with Systemd
sudo systemctl restart apache2
If Apache fails to restart, check the Apache error logs. For Homebrew Apache, these are typically in /usr/local/var/log/httpd/error_log. For System Apache, /var/log/apache2/error_log.
5. Clear Browser Cache and Test
Sometimes browsers cache redirect information or previous connection attempts.
- Clear your browser's cache and cookies.
- Try accessing your site in an incognito/private browsing window.
- Test again using
curl -v https://yourdomain.localto verify the SSL handshake is now successful:
curl -v https://yourdomain.local
Look for output indicating a successful TLS handshake and HTTP/2 or HTTP/1.1 response from your server.
6. Check Firewall or Security Software
While less common for ssl_error_rx_record_too_long (which implies a connection was made but with the wrong protocol), ensure your macOS firewall or any third-party security software isn't blocking incoming connections to port 443 for your Apache instance.
You can check your macOS firewall settings under System Settings > Network > Firewall. If enabled, ensure Apache (httpd) is allowed to receive incoming connections.
By methodically following these steps, you should be able to identify and resolve the ssl_error_rx_record_too_long issue, getting your local Apache SSL environment on macOS running smoothly.
Our Production Verification Guarantee
Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.