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

  1. 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 to myhost.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.
  2. 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.com to www.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.
  3. 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.
  4. 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.com to mylabel.example.com.
    • Why it works: These are fundamental rules of DNS name syntax enforced by RFCs to ensure consistent parsing and resolution.
  5. 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 be TXT "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.
  6. 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 IN for 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.1 should be www 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.

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.

Want structured learning?

Take the full Dns course →