The main site comes up, but shop.example.com or staging.example.com gives a DNS_PROBE_FINISHED_NXDOMAIN error or falls through to the host's default page. The problem is almost always one of three things: the DNS record wasn't created, the record was created but in the wrong Zone, or the VirtualHost on the server isn't defined for that name. This article is exactly the path you need to follow, plus two traps that few people address in time: SSL certificates and abandoned subdomains.
What a subdomain is in DNS and where it gets registered
A subdomain is a hostname, not an independent domain. That means it's written in the parent domain's Zone file as an A or CNAME record. If you manage DNS from your hosting panel, you usually see a simple form; if you use a separate DNS service, you have to write the record yourself:
shop 3600 IN A 185.xx.xx.xx
staging 3600 IN CNAME shop.example.com.
* 3600 IN A 185.xx.xx.xx
First point: in the Zone file, you write the hostname without the parent domain. Writing shop.example.com. IN A ... in the Zone of example.com causes a record named shop.example.com.example.com to be created. This mistake doesn't happen in graphical panels, but when you write the Zone file by hand or use an API, it's seen a lot. The way to spot it is simple: dig shop.example.com returns NXDOMAIN even though the record is in the file.
Second point: don't put a CNAME on the domain root (@). The DNS standard forbids this, and some resolvers silently ignore it. Use A for the root.
Wildcard record: convenient, but with one condition
The * record sends any name that doesn't have a dedicated record to one IP. It's great for test environments where you constantly create random subdomains. But it has two limitations that are annoying in practice. First, a wildcard only covers one level: *.example.com doesn't answer for a.b.example.com. Second, if you later want to deliberately take a subdomain offline, you can't; because the wildcard catches everything. The only way is to create an explicit record with an invalid value, which itself becomes technical debt.
SSL certificate for a subdomain: this is where they go wrong
An SSL certificate on the main domain does nothing for a subdomain. If you've obtained a certificate for example.com and brought up shop.example.com on the same server, the browser gives a NET::ERR_CERT_COMMON_NAME_INVALID error for the subdomain. This error doesn't show up in the server log because the request never reaches the application; at the very least, the TLS handshake is broken. Many people read the Nginx log for hours and find nothing.
You have three options:
| Method | Coverage | Real cost |
|---|---|---|
| Separate certificate for each subdomain | Precise and controlled | Renewal and automation for each one separately |
| Wildcard certificate | *.example.com one level | Requires DNS validation and publishing a TXT record |
| Multi-domain certificate (SAN) | A specific list of names | Every new subdomain means reissuing the certificate |
If the number of subdomains is fixed and small, I'd choose SAN; it's simpler and more predictable. If you constantly create and delete subdomains, wildcard is more economical, provided you set up its renewal automation properly. With Certbot, this requires a command with the --manual --preferred-challenges dns flag, and since you validate DNS manually, automatic renewal breaks. This is where they go wrong: they get a wildcard certificate, three months later they forget to renew it manually, and Monday morning all subdomains give a certificate error at the same time.
VirtualHost and ServerAlias
After DNS and SSL, it's the web server's turn. In Nginx you must write server_name in full:
server {
listen 443 ssl;
server_name shop.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/shop;
}
If you don't put the subdomain in server_name, Nginx sends it to the first VirtualHost on that port. The result: you see the main site, but at the subdomain address. This is exactly the situation where the user thinks DNS is broken, while DNS is fine and the problem is on the server. With curl -I https://shop.example.com and looking at the Server header and the returned content, it becomes clear quickly.
How an abandoned subdomain leads to compromise
Take this section seriously. A subdomain like old-panel.example.com was pointed last year at a cloud server. You emptied that server, but you didn't delete the DNS record. Now anyone can take that same IP and bring up content on old-panel.example.com that is completely legitimate from the browser's point of view. If you've set a cookie on the main domain with the domain .example.com, that cookie also goes to this subdomain. This class of attack has a name: Subdomain Takeover.
You won't see its signs in the log. You usually find out from the outside. To find them, pull the list of subdomains from Certificate Transparency and check each one with dig +short. Any record that points to an IP or external service that is no longer yours must be deleted that same day. If the number of subdomains is large, delegate this to a cron script and run it weekly.
A side note: if you use WordPress multisite with subdomains, every new site is a fresh subdomain, and this very thing complicates DNS and SSL management. Before choosing this architecture, read the cost-benefit analysis of WordPress multisite; in many cases, several separate installations are less troublesome.
Practical setup checklist
- Create the
AorCNAMErecord in the parent domain's Zone and verify it withdig shop.example.com +short. - Obtain the appropriate SSL certificate and put the expiry date in monitoring, not in your mental calendar.
- Add
server_namein the web server and see the correct response withcurl -I. - If it's WordPress, update the site address in the database; otherwise you'll get a redirect loop.
- Set up a scheduled task to review unused subdomains.
For faster setup, Linux hosting lets you define a subdomain and install a certificate from the same panel, and you don't need to write the Zone file by hand. If you work with WordPress and want to separate a test environment, setting up WordPress staging shows a safer path so the test subdomain doesn't connect to the main domain. For terminal commands, ServerNet documentation is a quicker reference.
And if you just want to know how many subdomains you have right now and which ones are dead, free tools are a good starting point. The one thing you should do this week is this: pull the list of subdomains and delete any record that points to an external service that is no longer yours. The rest of the work can be done later; this one can't.
Frequently asked questions
Does a subdomain require buying a new domain?
No. A subdomain is part of the parent domain and is registered in the same Zone. You just need to create a DNS record and define a VirtualHost for it on the server. You don't pay any extra cost for the name itself, but if a separate SSL certificate is needed, that cost is separate.
Why does my subdomain open but show the main site?
Because the DNS record is correct but the web server doesn't recognize the hostname and sends the request to the first VirtualHost on that port. You just need to add server_name in Nginx or ServerAlias in Apache and restart the service.
Does a wildcard certificate work for all subdomains?
It only covers one level. *.example.com covers shop.example.com but not a.shop.example.com. For the second level, you need a separate certificate or a separate wildcard record.
How do I know a subdomain is abandoned and dangerous?
With dig +short subdomainname, look at the record's value. If it points to an IP or cloud service that is no longer under your control, delete that record. To be sure, pull the list of subdomains from Certificate Transparency and review them all once.
Comments 0
No comments yet — be the first!