Troubleshooting Broken Subdomains by Inspecting Root HTTP Headers
When a newly created subdomain refuses to load or behaves erratically, analyzing the root response headers is the fastest way to diagnose the underlying routing, DNS, or server configuration failure. By inspecting the precise HTTP status codes, server tokens, and redirection paths returned by your web server, you can pinpoint exactly where the request is breaking down before it ever reaches your application layer.
To quickly inspect these values without cluttering your terminal, you can use the HTTP Headers Checker to instantly reveal the exact server response codes, content types, and routing hops for any web address.
Understanding Subdomain Resolution and HTTP Headers
A subdomain request relies on a precise chain of events starting from global DNS propagation and ending with your origin server's virtual host configuration. When you type app.example.com into a browser, the client queries your authoritative DNS provider for an A, AAAA, or CNAME record pointing to an IP address (such as 192.0.2.25 or 2001:db8::50). Once the browser connects to that IP address over TLS, it sends an HTTP request with a Host header set to app.example.com.
If your web server receives this request but lacks a matching virtual host block, it defaults to the primary server block or throws a generic error. Inspecting the HTTP headers returned during this handshake reveals whether the request hit the correct server block, triggered an unintended redirect, or failed due to a missing SSL certificate.
Step-by-Step Subdomain HTTP Header Troubleshooting
Isolating a broken subdomain requires a systematic approach. Follow these steps to trace the request from the command line and verify your server responses.
Step 1: Verify DNS Resolution and IP Binding
Before checking headers, ensure your subdomain is actually pointing to the intended server. Run a standard DNS lookup to confirm the IP address:
dig +short app.example.com A
If the returned IP address matches your hosting provider or load balancer (e.g., 192.0.2.10), proceed to the next step. If it returns an old IP or NXDOMAIN, your DNS records have not propagated or are misconfigured.
Step 2: Test Direct HTTP Headers with cURL
Use cURL to fetch the headers directly from the server. The -I flag requests only the header information, while -L follows redirects, which is crucial for catching infinite redirect loops.
curl -I -L https://app.example.com
Examine the output carefully. A healthy response typically looks like this:
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Wed, 10 Oct 2024 14:00:00 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Strict-Transport-Security: max-age=31536000
Step 3: Inspect SSL/TLS Handshake Issues
Many broken subdomains fail silently due to mismatched SNI (Server Name Indication) or expired certificates. If your wildcard certificate does not cover the specific subdomain depth, the TLS handshake will drop. Test the certificate chain using OpenSSL:
openssl s_client -connect app.example.com:443 -servername app.example.com
Look for the Verification: OK line and check the subject and issuer fields to ensure the certificate explicitly validates your subdomain.
Step 4: Compare Direct Server IP Headers
If your subdomain sits behind a Content Delivery Network (CDN) or reverse proxy, headers can change depending on whether you hit the edge or the origin. Bypass the edge by querying the origin IP directly (assuming you have permission and direct access to 192.0.2.15):
curl -I -H "Host: app.example.com" https://192.0.2.15 --insecure
Comparing the edge headers to the origin headers exposes caching discrepancies, missing proxy headers, or incorrect SSL termination settings.
Comparing Common Subdomain HTTP Response Codes
| Status Code | Primary Meaning | Common Subdomain Cause | Recommended Fix |
|---|---|---|---|
200 OK |
Successful Request | None (Normal operation) | Monitor performance and caching. |
301/302 |
Redirection | Forced HTTPS rule or trailing slash mismatch | Check web server rewrite rules and HSTS settings. |
403 Forbidden |
Access Denied | Missing index file, incorrect file permissions, or WAF block | Verify document root permissions and firewall logs. |
404 Not Found |
Resource Missing | Unmatched virtual host block or incorrect document root | Ensure server block server_name matches your subdomain exactly. |
502 Bad Gateway |
Upstream Failure | Reverse proxy cannot reach application port (e.g., Node.js/PHP-FPM) | Check if your backend application service is running locally. |
523 Origin Unreachable |
CDN Error | CDN cannot connect to origin server IP (192.0.2.20) |
Update DNS or firewall rules to allow CDN edge IPs. |
Fixing Configuration Errors in Popular Web Servers
Once your HTTP header inspection highlights an error, apply the fix in your web server configuration.
Nginx Virtual Host Configuration
If your subdomain returns a 404 or serves the wrong website, your Nginx server_name directive is likely missing or overridden by a default catch-all block. Open your server block configuration (typically located in /etc/nginx/sites-available/) and ensure the configuration matches this pattern:
server {
listen 80;
listen [::]:80;
server_name app.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/app;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
After saving, test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
Apache Virtual Host Configuration
For Apache web servers, verify your VirtualHost declarations inside your configuration files (such as /etc/apache2/sites-available/). Make sure ServerName and ServerAlias are declared accurately:
<VirtualHost *:443>
ServerName app.example.com
DocumentRoot /var/www/app
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
<Directory /var/www/app>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Restart Apache to apply changes:
sudo apache2ctl configtest
sudo systemctl restart apache2
Subdomain Troubleshooting Checklist
- Confirm DNS A or CNAME record resolves to the correct IP address.
- Check HTTP response headers using
curlor an online tool to identify error codes. - Verify that the web server virtual host
server_namematches the subdomain string. - Inspect SSL/TLS certificates to ensure they cover the specific subdomain level.
- Test local application responsiveness behind any reverse proxy or load balancer.
- Clear browser cache or test in incognito mode to avoid cached redirect loops.