The BIND DNS server is failing to validate DNS records, reporting a "checknames failure" because it’s encountering invalid characters or formats in your zone files.
Common Causes and Fixes
-
Invalid Characters in Hostnames:
- Diagnosis: Manually inspect your zone files for hostnames containing characters outside of the A-Z, a-z, 0-9, and hyphen (-) set. Common culprits include underscores (
_), periods at the end of labels (except for the FQDN terminator), or other special characters.# Example: Check for underscores in a zone file grep -E '[^a-zA-Z0-9.-]' your_zone_file.db - Fix: Remove or replace invalid characters. For example, if you have
_myhost.example.com, change it tomyhost.example.com. If you intended a CNAME for_sip._tcp.example.com, this is valid for SRV records but not directly as a hostname in other record types. - Why it works: BIND strictly enforces DNS naming conventions, which do not permit underscores or other special characters in standard hostname labels.
- Diagnosis: Manually inspect your zone files for hostnames containing characters outside of the A-Z, a-z, 0-9, and hyphen (-) set. Common culprits include underscores (
-
Unterminated FQDNs:
- Diagnosis: Ensure that all fully qualified domain names (FQDNs) in your zone file end with a trailing dot (
.). If a name doesn’t end with a dot, BIND appends the zone’s origin, which can lead to unintended FQDNs or invalid names if the origin itself is problematic.# Example: Find lines that might represent unterminated FQDNs (look for names without trailing dots) # This is a simplified check; actual inspection is often needed. awk '!/(\s+IN\s+SOA|\s+IN\s+NS|\s+IN\s+MX|\s+IN\s+AAAA|\s+IN\s+A|\s+IN\s+CNAME|\s+IN\s+TXT|\s+IN\s+SRV)/ { for(i=1; i<=NF; i++) if ($i ~ /^[a-zA-Z0-9.-]+$/ && $i !~ /\.$/) print "Potentially missing trailing dot: " $i }' your_zone_file.db - Fix: Add a trailing dot to all FQDNs. For example, change
www.example.comtowww.example.com.. - Why it works: The trailing dot explicitly signifies the root of the DNS hierarchy, preventing BIND from appending the zone’s origin and potentially creating an invalid or unintended name.
- Diagnosis: Ensure that all fully qualified domain names (FQDNs) in your zone file end with a trailing dot (
-
Invalid Label Lengths:
- Diagnosis: DNS labels (the parts between dots in a domain name) have a maximum length of 63 characters. Check for any labels exceeding this limit.
# Example: Check for labels longer than 63 characters awk '{ for(i=1; i<=NF; i++) { if (length($i) > 63 && $i ~ /^[a-zA-Z0-9.-]+\.$/) print "Label too long: " $i } }' your_zone_file.db - Fix: Shorten the offending labels.
- Why it works: The DNS protocol specifies a maximum length for each label in a domain name to maintain efficiency and compatibility across different DNS implementations.
- Diagnosis: DNS labels (the parts between dots in a domain name) have a maximum length of 63 characters. Check for any labels exceeding this limit.
-
Invalid Domain Name Structure:
- Diagnosis: Domain names cannot start or end with a hyphen (
-). Also, a label cannot consist solely of digits if it’s not part of a valid IP address representation (though this is less common for hostnames and more for specific record types or internal representations).# Example: Check for labels starting or ending with hyphens grep -E '(-[a-zA-Z0-9.]+|\.[a-zA-Z0-9-]+\.)' your_zone_file.db - Fix: Remove leading or trailing hyphens from labels. For instance, change
-mylabel.example.comtomylabel.example.com. - Why it works: These are fundamental rules of DNS name syntax enforced by RFCs to ensure consistent parsing and resolution.
- Diagnosis: Domain names cannot start or end with a hyphen (
-
Incorrectly Formatted TXT Records:
- Diagnosis: TXT records can contain arbitrary text, but this text must be enclosed in double quotes (
"). If you have unquoted text or quotes within the text that aren’t escaped, BIND will flag it.# Example: Find TXT records with improperly quoted strings awk '/IN\s+TXT/ { for(i=3; i<=NF; i++) if ($i !~ /^"/) print "Unquoted TXT data: " $i }' your_zone_file.db - Fix: Enclose all TXT record data in double quotes. If your text contains a double quote, escape it with a backslash (
\). Example:TXT "This is a "quoted" string."should beTXT "This is a \"quoted\" string.". - Why it works: The double quotes define the boundaries of the TXT string, and escaping is necessary to differentiate literal quotes within the data from the delimiters.
- Diagnosis: TXT records can contain arbitrary text, but this text must be enclosed in double quotes (
-
Missing TTL or Class/Type on Records:
- Diagnosis: Every resource record (except for the SOA and NS records at the zone apex, which implicitly inherit TTL or have specific syntax) requires a Time To Live (TTL), a class (usually
INfor Internet), and a record type.# Example: Check for lines missing TTL, Class, or Type (simplified) awk '/^[a-zA-Z0-9.-]+\s+[^0-9]/ { print "Missing TTL or Type: " $0 }' your_zone_file.db - Fix: Add the missing TTL, class, and type. For example,
www IN A 192.0.2.1should bewww 3600 IN A 192.0.2.1. - Why it works: These components are essential for BIND and other DNS servers to correctly interpret and serve the record’s information.
- Diagnosis: Every resource record (except for the SOA and NS records at the zone apex, which implicitly inherit TTL or have specific syntax) requires a Time To Live (TTL), a class (usually
After fixing these issues and reloading BIND (rndc reload or systemctl reload named), you might encounter the next common error: zone your_zone_file.db/IN: bad zone transfer.