
What Is a Fully Qualified Domain Name (FQDN)?
You add a CNAME record pointing www to example.net, save it, and the site breaks. A lookup shows the record now points to example.net.example.com — a name that doesn't exist. Or a server inside Kubernetes takes seconds to resolve api.stripe.com because it's trying api.stripe.com.default.svc.cluster.local first. Both problems come from the same concept: whether a domain name is fully qualified or not.
This article explains what a fully qualified domain name (FQDN) is, how it's structured, why the trailing dot matters, how FQDNs differ from relative names and partially qualified names, and where getting it wrong causes real breakage — in zone files, resolver search lists, certificates, and mail servers. For background on how names map onto the DNS tree, see the difference between a DNS zone and a domain.
What Is a Fully Qualified Domain Name?
A fully qualified domain name (FQDN) is the complete, unambiguous name of a node in the DNS tree, listing every label from the specific host all the way up to the root. It's also called an absolute domain name.
Take www.example.com. as an example:
wwwis the host or subdomain label.exampleis the second-level domain.comis the top-level domain.- The final
.represents the root of the DNS hierarchy.
Read right to left, an FQDN traces a path from the root down through each level of delegation: root, then com, then example, then www. Because it includes every level, an FQDN means the same thing no matter where or how it's used. There's no context that could change which host it refers to.
The trailing dot
Strictly speaking, an FQDN ends with a dot. The root of the DNS tree has an empty label, and the trailing dot is how you write it. So www.example.com. is the formal FQDN, and www.example.com without the dot is, technically, a name that could be relative.
In everyday use — browsers, email addresses, most application settings — the trailing dot is omitted, and software treats names with at least one dot as absolute anyway. But in zone files, resolver configuration, and some APIs, the dot is significant and changes the meaning of the name. You can see that the dot is legitimate by resolving it directly:
dig +short www.example.com.
dig +short example.com.
Both work exactly like the dotless versions, because DNS itself always works with fully qualified names internally.
Structure and Length Limits
DNS names have strict limits defined in RFC 1035:
| Element | Limit |
|---|---|
| Each label | 1 to 63 characters |
| Full name, in text form | 253 characters (excluding the trailing dot) |
| Full name, on the wire | 255 bytes, including length bytes and the root |
| Hostname characters | Letters, digits, and hyphens; no leading or trailing hyphen |
The hostname rules (sometimes called the LDH rule, for letters, digits, hyphen) come from RFC 952 and RFC 1123. DNS itself can technically carry other bytes in labels, which is why records like _dmarc.example.com and _sip._tcp.example.com are valid even though underscores aren't allowed in hostnames. Non-ASCII names like münchen.de are stored as ASCII using Punycode; internationalized domain names and Punycode covers that encoding.
Labels are case-insensitive: WWW.Example.COM. and www.example.com. are the same FQDN.
Validating an FQDN in code
If you accept hostnames as user input — for webhooks, allowlists, or certificate requests — validate the syntax before using it:
import re
LABEL = re.compile(r"^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$")
def is_valid_fqdn(name: str) -> bool:
"""Check hostname-style FQDN syntax (letters, digits, hyphens)."""
if name.endswith("."):
name = name[:-1] # the trailing dot is the root, not a label
if not name or len(name) > 253:
return False
labels = name.split(".")
if len(labels) < 2:
return False # a single label is not fully qualified
if labels[-1].isdigit():
return False # TLDs are never all-numeric
return all(LABEL.match(label) for label in labels)
for candidate in [
"www.example.com.",
"www.example.com",
"localhost",
"-bad.example.com",
"a" * 64 + ".example.com",
"xn--mnchen-3ya.de",
"192.0.2.10",
]:
print(f"{candidate[:40]:42} {is_valid_fqdn(candidate)}")
www.example.com. True
www.example.com True
localhost False
-bad.example.com False
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa False
xn--mnchen-3ya.de True
192.0.2.10 False
The function strips an optional trailing dot, enforces the total and per-label length limits, requires at least two labels, rejects all-numeric TLDs (which also catches bare IPv4 addresses), and checks each label against the LDH rule. It validates syntax only; whether the name actually resolves is a separate DNS lookup.
FQDN vs Relative and Partially Qualified Names
A relative domain name is one that's interpreted relative to some origin or search domain. Whether a name is absolute or relative depends on context:
| Name | In a zone file for example.com | In a browser or email client |
|---|---|---|
www | Becomes www.example.com. | Single-label name, resolved via search domains if at all |
www.example.com | Becomes www.example.com.example.com. | Treated as www.example.com. |
www.example.com. | Stays www.example.com. | Treated as www.example.com. |
@ | The zone apex, example.com. | Not meaningful |
A partially qualified domain name (PQDN) is any name that isn't fully qualified — www, mail, or intranet used inside a corporate network, for example. PQDNs are convenient for humans but depend on configuration to resolve, which makes them fragile.
Where FQDNs Matter Most
1. Zone files
The most common FQDN mistake is in DNS zone files. Any name without a trailing dot is relative to the zone's $ORIGIN, so it gets the zone name appended:
$ORIGIN example.com.
$TTL 3600
@ IN NS ns1.example.com. ; correct: absolute
www IN CNAME example.net. ; correct: points to example.net
shop IN CNAME example.net ; WRONG: becomes example.net.example.com.
mail IN A 192.0.2.25
@ IN MX 10 mail ; fine: relative, expands to mail.example.com.
The shop record is the classic bug. Because example.net lacks a trailing dot, the server expands it to example.net.example.com.. The mail target in the MX line is intentionally relative and correctly becomes mail.example.com.. BIND's named-checkzone will load both without complaint, since both are syntactically valid — the only way to catch it is to read the output:
named-checkzone -D -o - example.com db.example.com | grep -E "CNAME|MX"
The -D -o - options dump the zone in canonical form to standard output, with every name fully expanded, so a target like example.net.example.com. stands out immediately. This applies to every record type that contains a hostname: CNAME, MX, NS, PTR, and SRV targets. NS records and PTR records are especially sensitive, since a wrong target there breaks delegation or reverse lookups.
Web-based DNS dashboards usually add the trailing dot or the zone name for you, but behavior varies. Some treat a target without a dot as absolute; others append the zone. When in doubt, check the record with dig after saving it.
2. Resolver search domains and ndots
Stub resolvers on Linux and macOS can append search domains to names that look relative. The behavior is controlled by /etc/resolv.conf:
nameserver 192.0.2.53
search corp.example.com example.com
options ndots:1
With this configuration, a lookup for intranet (zero dots, fewer than ndots) is tried as intranet.corp.example.com. first, then intranet.example.com., then intranet. as-is. A name with at least one dot is tried as-is first.
Kubernetes pods ship with options ndots:5 and several cluster search domains. That means a lookup for api.stripe.com (two dots, fewer than five) is first tried with each search domain appended — api.stripe.com.default.svc.cluster.local. and so on — before the real name. Each attempt is a wasted query that returns NXDOMAIN. Writing the FQDN with a trailing dot skips the search list entirely:
# Inside a pod: compare the two
getent hosts api.stripe.com
getent hosts api.stripe.com.
Both return the same address, but the second sends a single query. In application config for external services, using api.stripe.com. or lowering ndots in the pod's dnsConfig can cut DNS traffic and latency noticeably.
3. A machine's own FQDN
Servers have a short hostname and an FQDN. Mail servers, Kerberos, and many monitoring tools need the FQDN to be correct.
hostname # short name, e.g. web01
hostname -f # FQDN, e.g. web01.example.com
In Python, socket.getfqdn() returns the same information:
import socket
print(socket.gethostname()) # short hostname
print(socket.getfqdn()) # fully qualified name
On Windows, PowerShell can read it from the DNS client:
[System.Net.Dns]::GetHostEntry($env:COMPUTERNAME).HostName
If hostname -f returns only the short name, the system's /etc/hosts entry or DNS search configuration is incomplete. Fix it by listing the FQDN first on the host's line in /etc/hosts, for example 192.0.2.10 web01.example.com web01.
4. Email
SMTP servers announce themselves with an FQDN in their HELO or EHLO greeting, and receiving servers increasingly reject or penalize greetings that aren't valid FQDNs or don't match the sending IP's reverse DNS. The FQDN in the greeting, the PTR record for the IP, and the A record for that name should all agree.
5. TLS certificates
Certificates list names in their Subject Alternative Name field without a trailing dot. When you request a certificate, use the exact FQDNs clients will connect to — www.example.com and example.com are separate names, and a certificate for one doesn't cover the other. Wildcard certificates cover one label only: *.example.com matches shop.example.com but not dev.shop.example.com.
Common FQDN Mistakes
- Missing trailing dots in zone files, causing the zone name to be appended to CNAME, MX, NS, or SRV targets.
- Single-label hostnames in production configs that only work because of a search domain on one particular network.
- Assuming
example.comandwww.example.comare interchangeable. They are different FQDNs and need separate records and certificate coverage. The post on setting up subdomains covers how each is configured. - Unqualified names in container environments, multiplying queries through long search lists.
- Mismatched server FQDNs between the HELO greeting, PTR record, and forward A record on mail servers.
FQDN FAQ
www.example.com. is a fully qualified domain name. It names the host www in the example domain under the com TLD, with the trailing dot representing the DNS root.
Formally, yes — the trailing dot marks the root and makes the name absolute. In browsers and most applications it's omitted, but in zone files and resolver configuration it changes how the name is interpreted.
A hostname is usually the short name of a machine, such as web01. The FQDN adds every domain level above it, such as web01.example.com., so it's unambiguous everywhere.
Yes. example.com. is the fully qualified name of the domain's apex. An FQDN doesn't need a www or other subdomain label.
A full domain name can be up to 253 characters in text form, with each label up to 63 characters. On the wire, the limit is 255 bytes.
On Linux and macOS run hostname -f. In Python, use socket.getfqdn(). On Windows, [System.Net.Dns]::GetHostEntry($env:COMPUTERNAME).HostName in PowerShell shows it.
The target was written without a trailing dot in a zone file or a DNS panel that treats such names as relative, so the zone name was appended. Add the trailing dot, for example example.net., to make it absolute.
Hostnames can't, but DNS names can. Service and policy records such as _dmarc.example.com and _sip._tcp.example.com use underscores deliberately so they can't collide with real hostnames.
Conclusion
A fully qualified domain name is the complete, absolute address of a node in DNS, listing every label from the host up to the root and, formally, ending with a dot. Most of the time the distinction is invisible because software quietly treats dotted names as absolute. But in the places where it matters — zone files, resolver search lists, server identity, mail greetings, and certificates — the difference between a relative and a fully qualified name decides whether things resolve correctly.
The habits that prevent trouble are simple: always end hostname targets in zone files with a trailing dot, use FQDNs rather than short names in production configuration, set each server's FQDN correctly, and verify records with dig after you change them.
Here are some useful references for going deeper on FQDNs:
- RFC 1034: Domain Names - Concepts and Facilities — defines absolute and relative domain names and the role of the root label.
- RFC 1035: Domain Names - Implementation and Specification — specifies label and name length limits and zone file syntax.
- RFC 1123: Requirements for Internet Hosts — updates hostname syntax rules, including labels that start with digits.
- Kubernetes Documentation: DNS for Services and Pods — explains search domains, ndots, and pod DNS configuration.
- BIND 9 Documentation: BIND 9 Administrator Reference Manual — covers zone file syntax, $ORIGIN, and named-checkzone.


