Chapter 5. BIND 9 Configuration Reference

Table of Contents

Configuration File Elements
Address Match Lists
Comment Syntax
Configuration File Grammar
acl Statement Grammar
acl Statement Definition and Usage
controls Statement Grammar
controls Statement Definition and Usage
include Statement Grammar
include Statement Definition and Usage
key Statement Grammar
key Statement Definition and Usage
logging Statement Grammar
logging Statement Definition and Usage
masters Statement Grammar
masters Statement Definition and Usage
options Statement Grammar
options Statement Definition and Usage
server Statement Grammar
server Statement Definition and Usage
statistics-channels Statement Grammar
statistics-channels Statement Definition and Usage
trusted-keys Statement Grammar
trusted-keys Statement Definition and Usage
managed-keys Statement Grammar
managed-keys Statement Definition and Usage
view Statement Grammar
view Statement Definition and Usage
zone Statement Grammar
zone Statement Definition and Usage
Zone File
Types of Resource Records and When to Use Them
Discussion of MX Records
Setting TTLs
Inverse Mapping in IPv4
Other Zone File Directives
BIND Master File Extension: the $GENERATE Directive
Additional File Formats
BIND9 Statistics
The Statistics File
Statistics Counters

BIND 9 configuration is broadly similar to BIND 8; however, there are a few new areas of configuration, such as views. BIND 8 configuration files should work with few alterations in BIND 9, although more complex configurations should be reviewed to check if they can be more efficiently implemented using the new features found in BIND 9.

BIND 4 configuration files can be converted to the new format using the shell script contrib/named-bootconf/

Configuration File Elements

Following is a list of elements used throughout the BIND configuration file documentation:


The name of an address_match_list as defined by the acl statement.


A list of one or more ip_addr, ip_prefix, key_id, or acl_name elements, see the section called “Address Match Lists”.


A named list of one or more ip_addr with optional key_id and/or ip_port. A masters_list may include other masters_lists.


A quoted string which will be used as a DNS name, for example "my.test.domain".


A list of one or more domain_name elements.


One to four integers valued 0 through 255 separated by dots (`.'), such as 123, 45.67 or


An IPv4 address with exactly four elements in dotted_decimal notation.


An IPv6 address, such as 2001:db8::1234. IPv6 scoped addresses that have ambiguity on their scope zones must be disambiguated by an appropriate zone ID with the percent character (`%') as delimiter. It is strongly recommended to use string zone names rather than numeric identifiers, in order to be robust against system configuration changes. However, since there is no standard mapping for such names and identifier values, currently only interface names as link identifiers are supported, assuming one-to-one mapping between interfaces and links. For example, a link-local address fe80::1 on the link attached to the interface ne0 can be specified as fe80::1%ne0. Note that on most systems link-local addresses always have the ambiguity, and need to be disambiguated.


An ip4_addr or ip6_addr.


A number between 0 and 63, used to select a differentiated services code point (DSCP) value for use with outgoing traffic on operating systems that support DSCP.


An IP port number. The number is limited to 0 through 65535, with values below 1024 typically restricted to use by processes running as root. In some cases, an asterisk (`*') character can be used as a placeholder to select a random high-numbered port.


An IP network specified as an ip_addr, followed by a slash (`/') and then the number of bits in the netmask. Trailing zeros in a ip_addr may omitted. For example, 127/8 is the network with netmask and is network with netmask

When specifying a prefix involving a IPv6 scoped address the scope may be omitted. In that case the prefix will match packets from any scope.


A domain_name representing the name of a shared key, to be used for transaction security.


A list of one or more key_ids, separated by semicolons and ending with a semicolon.


A non-negative 32-bit integer (i.e., a number between 0 and 4294967295, inclusive). Its acceptable value might be further limited by the context in which it is used.


A non-negative real number that can be specified to the nearest one hundredth. Up to five digits can be specified before a decimal point, and up to two digits after, so the maximum value is 99999.99. Acceptable values might be further limited by the context in which it is used.


A quoted string which will be used as a pathname, such as zones/master/my.test.domain.


A list of an ip_port or a port range. A port range is specified in the form of range followed by two ip_ports, port_low and port_high, which represents port numbers from port_low through port_high, inclusive. port_low must not be larger than port_high. For example, range 1024 65535 represents ports from 1024 through 65535. In either case an asterisk (`*') character is not allowed as a valid ip_port.


A 64-bit unsigned integer, or the keywords unlimited or default.

Integers may take values 0 <= value <= 18446744073709551615, though certain parameters (such as max-journal-size) may use a more limited range within these extremes. In most cases, setting a value to 0 does not literally mean zero; it means "undefined" or "as big as possible", depending on the context. See the explanations of particular parameters that use size_spec for details on how they interpret its use.

Numeric values can optionally be followed by a scaling factor: K or k for kilobytes, M or m for megabytes, and G or g for gigabytes, which scale by 1024, 1024*1024, and 1024*1024*1024 respectively.

unlimited generally means "as big as possible", and is usually the best way to safely set a very large number.

default uses the limit that was in force when the server was started.


size_spec or integer value followed by '%' to represent percents.

The behavior is exactly the same as size_spec, but size_or_percent allows also to specify a positive integer value followed by '%' sign to represent percents.


Either yes or no. The words true and false are also accepted, as are the numbers 1 and 0.


One of yes, no, notify, notify-passive, refresh or passive. When used in a zone, notify-passive, refresh, and passive are restricted to slave and stub zones.

Address Match Lists


address_match_list = address_match_list_element ; ...

address_match_list_element = [ ! ] ( ip_address | ip_prefix |
     key key_id | acl_name | { address_match_list } )

Definition and Usage

Address match lists are primarily used to determine access control for various server operations. They are also used in the listen-on and sortlist statements. The elements which constitute an address match list can be any of the following:

  • an IP address (IPv4 or IPv6)
  • an IP prefix (in `/' notation)
  • a key ID, as defined by the key statement
  • the name of an address match list defined with the acl statement
  • a nested address match list enclosed in braces

Elements can be negated with a leading exclamation mark (`!'), and the match list names "any", "none", "localhost", and "localnets" are predefined. More information on those names can be found in the description of the acl statement.

The addition of the key clause made the name of this syntactic element something of a misnomer, since security keys can be used to validate access without regard to a host or network address. Nonetheless, the term "address match list" is still used throughout the documentation.

When a given IP address or prefix is compared to an address match list, the comparison takes place in approximately O(1) time. However, key comparisons require that the list of keys be traversed until a matching key is found, and therefore may be somewhat slower.

The interpretation of a match depends on whether the list is being used for access control, defining listen-on ports, or in a sortlist, and whether the element was negated.

When used as an access control list, a non-negated match allows access and a negated match denies access. If there is no match, access is denied. The clauses allow-notify, allow-recursion, allow-recursion-on, allow-query, allow-query-on, allow-query-cache, allow-query-cache-on, allow-transfer, allow-update, allow-update-forwarding, blackhole, and keep-response-order all use address match lists. Similarly, the listen-on option will cause the server to refuse queries on any of the machine's addresses which do not match the list.

Order of insertion is significant. If more than one element in an ACL is found to match a given IP address or prefix, preference will be given to the one that came first in the ACL definition. Because of this first-match behavior, an element that defines a subset of another element in the list should come before the broader element, regardless of whether either is negated. For example, in 1.2.3/24; !; the element is completely useless because the algorithm will match any lookup for to the 1.2.3/24 element. Using !; 1.2.3/24 fixes that problem by having blocked by the negation, but all other 1.2.3.* hosts fall through.

Comment Syntax

The BIND 9 comment syntax allows for comments to appear anywhere that whitespace may appear in a BIND configuration file. To appeal to programmers of all kinds, they can be written in the C, C++, or shell/perl style.


/* This is a BIND comment as in C */

// This is a BIND comment as in C++

# This is a BIND comment as in common UNIX shells
# and perl

Definition and Usage

Comments may appear anywhere that whitespace may appear in a BIND configuration file.

C-style comments start with the two characters /* (slash, star) and end with */ (star, slash). Because they are completely delimited with these characters, they can be used to comment only a portion of a line or to span multiple lines.

C-style comments cannot be nested. For example, the following is not valid because the entire comment ends with the first */:

/* This is the start of a comment.
   This is still part of the comment.
/* This is an incorrect attempt at nesting a comment. */
   This is no longer in any comment. */

C++-style comments start with the two characters // (slash, slash) and continue to the end of the physical line. They cannot be continued across multiple physical lines; to have one logical comment span multiple lines, each line must use the // pair. For example:

// This is the start of a comment.  The next line
// is a new comment, even though it is logically
// part of the previous comment.

Shell-style (or perl-style, if you prefer) comments start with the character # (number sign) and continue to the end of the physical line, as in C++ comments. For example:

# This is the start of a comment.  The next line
# is a new comment, even though it is logically
# part of the previous comment.


You cannot use the semicolon (`;') character to start a comment such as you would in a zone file. The semicolon indicates the end of a configuration statement.

Configuration File Grammar

A BIND 9 configuration consists of statements and comments. Statements end with a semicolon. Statements and comments are the only elements that can appear without enclosing braces. Many statements contain a block of sub-statements, which are also terminated with a semicolon.

The following statements are supported:


defines a named IP address matching list, for access control and other uses.


declares control channels to be used by the rndc utility.


includes a file.


specifies key information for use in authentication and authorization using TSIG.


specifies what the server logs, and where the log messages are sent.


defines a named masters list for inclusion in stub and slave zones' masters or also-notify lists.


controls global server configuration options and sets defaults for other statements.


sets certain configuration options on a per-server basis.


declares communication channels to get access to named statistics.


defines trusted DNSSEC keys.


lists DNSSEC keys to be kept up to date using RFC 5011 trust anchor maintenance.


defines a view.


defines a zone.

The logging and options statements may only occur once per configuration.

acl Statement Grammar

acl string { address_match_element; ... };

acl Statement Definition and Usage

The acl statement assigns a symbolic name to an address match list. It gets its name from a primary use of address match lists: Access Control Lists (ACLs).

The following ACLs are built-in:


Matches all hosts.


Matches no hosts.


Matches the IPv4 and IPv6 addresses of all network interfaces on the system. When addresses are added or removed, the localhost ACL element is updated to reflect the changes.


Matches any host on an IPv4 or IPv6 network for which the system has an interface. When addresses are added or removed, the localnets ACL element is updated to reflect the changes. Some systems do not provide a way to determine the prefix lengths of local IPv6 addresses. In such a case, localnets only matches the local IPv6 addresses, just like localhost.

controls Statement Grammar

controls {
	inet ( ipv4_address | ipv6_address |
	    * ) [ port ( integer | * ) ] allow
	    { address_match_element; ... } [
	    keys { string; ... } ] [ read-only
	    boolean ];
	unix quoted_string perm integer
	    owner integer group integer [
	    keys { string; ... } ] [ read-only
	    boolean ];

controls Statement Definition and Usage

The controls statement declares control channels to be used by system administrators to control the operation of the name server. These control channels are used by the rndc utility to send commands to and retrieve non-DNS results from a name server.

An inet control channel is a TCP socket listening at the specified ip_port on the specified ip_addr, which can be an IPv4 or IPv6 address. An ip_addr of * (asterisk) is interpreted as the IPv4 wildcard address; connections will be accepted on any of the system's IPv4 addresses. To listen on the IPv6 wildcard address, use an ip_addr of ::. If you will only use rndc on the local host, using the loopback address ( or ::1) is recommended for maximum security.

If no port is specified, port 953 is used. The asterisk "*" cannot be used for ip_port.

The ability to issue commands over the control channel is restricted by the allow and keys clauses. Connections to the control channel are permitted based on the address_match_list. This is for simple IP address based filtering only; any key_id elements of the address_match_list are ignored.

A unix control channel is a UNIX domain socket listening at the specified path in the file system. Access to the socket is specified by the perm, owner and group clauses. Note on some platforms (SunOS and Solaris) the permissions (perm) are applied to the parent directory as the permissions on the socket itself are ignored.

The primary authorization mechanism of the command channel is the key_list, which contains a list of key_ids. Each key_id in the key_list is authorized to execute commands over the control channel. See Remote Name Daemon Control application in the section called “Administrative Tools”) for information about configuring keys in rndc.

If the read-only clause is enabled, the control channel is limited to the following set of read-only commands: nta -dump, null, status, showzone, testgen, and zonestatus. By default, read-only is not enabled and the control channel allows read-write access.

If no controls statement is present, named will set up a default control channel listening on the loopback address and its IPv6 counterpart ::1. In this case, and also when the controls statement is present but does not have a keys clause, named will attempt to load the command channel key from the file rndc.key in /etc (or whatever sysconfdir was specified as when BIND was built). To create a rndc.key file, run rndc-confgen -a.

The rndc.key feature was created to ease the transition of systems from BIND 8, which did not have digital signatures on its command channel messages and thus did not have a keys clause. It makes it possible to use an existing BIND 8 configuration file in BIND 9 unchanged, and still have rndc work the same way ndc worked in BIND 8, simply by executing the command rndc-confgen -a after BIND 9 is installed.

Since the rndc.key feature is only intended to allow the backward-compatible usage of BIND 8 configuration files, this feature does not have a high degree of configurability. You cannot easily change the key name or the size of the secret, so you should make a rndc.conf with your own key if you wish to change those things. The rndc.key file also has its permissions set such that only the owner of the file (the user that named is running as) can access it. If you desire greater flexibility in allowing other users to access rndc commands, then you need to create a rndc.conf file and make it group readable by a group that contains the users who should have access.

To disable the command channel, use an empty controls statement: controls { };.

include Statement Grammar

include filename;

include Statement Definition and Usage

The include statement inserts the specified file at the point where the include statement is encountered. The include statement facilitates the administration of configuration files by permitting the reading or writing of some things but not others. For example, the statement could include private keys that are readable only by the name server.

key Statement Grammar

key string {
	algorithm string;
	secret string;

key Statement Definition and Usage

The key statement defines a shared secret key for use with TSIG (see the section called “TSIG”) or the command channel (see the section called “controls Statement Definition and Usage”).

The key statement can occur at the top level of the configuration file or inside a view statement. Keys defined in top-level key statements can be used in all views. Keys intended for use in a controls statement (see the section called “controls Statement Definition and Usage”) must be defined at the top level.

The key_id, also known as the key name, is a domain name uniquely identifying the key. It can be used in a server statement to cause requests sent to that server to be signed with this key, or in address match lists to verify that incoming requests have been signed with a key matching this name, algorithm, and secret.

The algorithm_id is a string that specifies a security/authentication algorithm. The named server supports hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384 and hmac-sha512 TSIG authentication. Truncated hashes are supported by appending the minimum number of required bits preceded by a dash, e.g. hmac-sha1-80. The secret_string is the secret to be used by the algorithm, and is treated as a Base64 encoded string.

logging Statement Grammar

logging {
	category string { string; ... };
	channel string {
		buffered boolean;
		file quoted_string [ versions ( unlimited | integer ) ]
		    [ size size ] [ suffix ( increment | timestamp ) ];
		print-category boolean;
		print-severity boolean;
		print-time ( iso8601 | iso8601-utc | local | boolean );
		severity log_severity;
		syslog [ syslog_facility ];

logging Statement Definition and Usage

The logging statement configures a wide variety of logging options for the name server. Its channel phrase associates output methods, format options and severity levels with a name that can then be used with the category phrase to select how various classes of messages are logged.

Only one logging statement is used to define as many channels and categories as are wanted. If there is no logging statement, the logging configuration will be:

logging {
     category default { default_syslog; default_debug; };
     category unmatched { null; };

If named is started with the -L option, it logs to the specified file at startup, instead of using syslog. In this case the logging configuration will be:

logging {
     category default { default_logfile; default_debug; };
     category unmatched { null; };

The logging configuration is only established when the entire configuration file has been parsed. When the server is starting up, all logging messages regarding syntax errors in the configuration file go to the default channels, or to standard error if the -g option was specified.

The channel Phrase

All log output goes to one or more channels; you can make as many of them as you want.

Every channel definition must include a destination clause that says whether messages selected for the channel go to a file, to a particular syslog facility, to the standard error stream, or are discarded. It can optionally also limit the message severity level that will be accepted by the channel (the default is info), and whether to include a named-generated time stamp, the category name and/or severity level (the default is not to include any).

The null destination clause causes all messages sent to the channel to be discarded; in that case, other options for the channel are meaningless.

The file destination clause directs the channel to a disk file. It can include additional arguments to specify how large the file is allowed to become before it is rolled to a backup file (size), how many backup versions of the file will be saved each time this happens (versions), and the format to use for naming backup versions (suffix).

The size option is used to limit log file growth. If the file ever exceeds the specified size, then named will stop writing to the file unless it has a versions option associated with it. If backup versions are kept, the files are rolled as described below. If there is no versions option, no more data will be written to the log until some out-of-band mechanism removes or truncates the log to less than the maximum size. The default behavior is not to limit the size of the file.

File rolling only occurs when the file exceeds the size specified with the size option. No backup versions are kept by default; any existing log file is simply appended. The versions option specifies how many backup versions of the file should be kept. If set to unlimited, there is no limit.

The suffix option can be set to either increment or timestamp. If set to timestamp, then when a log file is rolled, it is saved with the current timestamp as a file suffix. If set to increment, then backup files are saved with incrementing numbers as suffixes; older files are renamed when rolling. For example, if versions is set to 3 and suffix to increment, then when filename.log reaches the size specified by size, filename.log.1 is renamed to filename.log.2, filename.log.0 is renamed to filename.log.1, and filename.log is renamed to filename.log.0, whereupon a new filename.log is opened.

Example usage of the size, versions, and suffix options:

channel an_example_channel {
    file "example.log" versions 3 size 20m suffix increment;
    print-time yes;
    print-category yes;

The syslog destination clause directs the channel to the system log. Its argument is a syslog facility as described in the syslog man page. Known facilities are kern, user, mail, daemon, auth, syslog, lpr, news, uucp, cron, authpriv, ftp, local0, local1, local2, local3, local4, local5, local6 and local7, however not all facilities are supported on all operating systems. How syslog will handle messages sent to this facility is described in the syslog.conf man page. If you have a system which uses a very old version of syslog that only uses two arguments to the openlog() function, then this clause is silently ignored.

On Windows machines syslog messages are directed to the EventViewer.

The severity clause works like syslog's "priorities", except that they can also be used if you are writing straight to a file rather than using syslog. Messages which are not at least of the severity level given will not be selected for the channel; messages of higher severity levels will be accepted.

If you are using syslog, then the syslog.conf priorities will also determine what eventually passes through. For example, defining a channel facility and severity as daemon and debug but only logging daemon.warning via syslog.conf will cause messages of severity info and notice to be dropped. If the situation were reversed, with named writing messages of only warning or higher, then syslogd would print all messages it received from the channel.

The stderr destination clause directs the channel to the server's standard error stream. This is intended for use when the server is running as a foreground process, for example when debugging a configuration.

The server can supply extensive debugging information when it is in debugging mode. If the server's global debug level is greater than zero, then debugging mode will be active. The global debug level is set either by starting the named server with the -d flag followed by a positive integer, or by running rndc trace. The global debug level can be set to zero, and debugging mode turned off, by running rndc notrace. All debugging messages in the server have a debug level, and higher debug levels give more detailed output. Channels that specify a specific debug severity, for example:

channel specific_debug_level {
    file "foo";
    severity debug 3;

will get debugging output of level 3 or less any time the server is in debugging mode, regardless of the global debugging level. Channels with dynamic severity use the server's global debug level to determine what messages to print.

print-time can be set to yes, no, or a time format specifier, which may be one of local, iso8601 or iso8601-utc. If set to no, then the date and time will not be logged. If set to yes or local, the date and time are logged in a human readable format, using the local time zone. If set to iso8601 the local time is logged in ISO8601 format. If set to iso8601-utc, then the date and time are logged in ISO8601 format, with time zone set to UTC. The default is no.

print-time may be specified for a syslog channel, but it is usually pointless since syslog also logs the date and time.

If print-category is requested, then the category of the message will be logged as well. Finally, if print-severity is on, then the severity level of the message will be logged. The print- options may be used in any combination, and will always be printed in the following order: time, category, severity. Here is an example where all three print- options are on:

28-Feb-2000 15:05:32.863 general: notice: running

If buffered has been turned on the output to files will not be flushed after each log entry. By default all log messages are flushed.

There are four predefined channels that are used for named's default logging as follows. If named is started with the -L then a fifth channel default_logfile is added. How they are used is described in the section called “The category Phrase”.

channel default_syslog {
    // send to syslog's daemon facility
    syslog daemon;
    // only send priority info and higher
    severity info;

channel default_debug {
    // write to in the working directory
    // Note: stderr is used instead of "" if
    // the server is started with the '-g' option.
    file "";
    // log at the server's current debug level
    severity dynamic;

channel default_stderr {
    // writes to stderr
    // only send priority info and higher
    severity info;

channel null {
   // toss anything sent to this channel

channel default_logfile {
    // this channel is only present if named is
    // started with the -L option, whose argument
    // provides the file name
    file "...";
    // log at the server's current debug level
    severity dynamic;

The default_debug channel has the special property that it only produces output when the server's debug level is nonzero. It normally writes to a file called in the server's working directory.

For security reasons, when the -u command line option is used, the file is created only after named has changed to the new UID, and any debug output generated while named is starting up and still running as root is discarded. If you need to capture this output, you must run the server with the -L option to specify a default logfile, or the -g option to log to standard error which you can redirect to a file.

Once a channel is defined, it cannot be redefined. Thus you cannot alter the built-in channels directly, but you can modify the default logging by pointing categories at channels you have defined.

The category Phrase

There are many categories, so you can send the logs you want to see wherever you want, without seeing logs you don't want. If you don't specify a list of channels for a category, then log messages in that category will be sent to the default category instead. If you don't specify a default category, the following "default default" is used:

category default { default_syslog; default_debug; };

If you start named with the -L option then the default category is:

category default { default_logfile; default_debug; };

As an example, let's say you want to log security events to a file, but you also want keep the default logging behavior. You'd specify the following:

channel my_security_channel {
    file "my_security_file";
    severity info;
category security {

To discard all messages in a category, specify the null channel:

category xfer-out { null; };
category notify { null; };

Following are the available categories and brief descriptions of the types of log information they contain. More categories may be added in future BIND releases.


Processing of client requests.


Logs nameservers that are skipped due to them being a CNAME rather than A / AAAA records.


Configuration file parsing and processing.


Messages relating to the databases used internally by the name server to store zone and cache data.


The default category defines the logging options for those categories where no specific configuration has been defined.


Delegation only. Logs queries that have been forced to NXDOMAIN as the result of a delegation-only zone or a delegation-only in a forward, hint or stub zone declaration.


Dispatching of incoming packets to the server modules where they are to be processed.


DNSSEC and TSIG protocol processing.


The "dnstap" DNS traffic capture system.


Log queries that have been forced to use plain DNS due to timeouts. This is often due to the remote servers not being RFC 1034 compliant (not always returning FORMERR or similar to EDNS queries and other extensions to the DNS when they are not understood). In other words, this is targeted at servers that fail to respond to DNS queries that they don't understand.

Note: the log message can also be due to packet loss. Before reporting servers for non-RFC 1034 compliance they should be re-tested to determine the nature of the non-compliance. This testing should prevent or reduce the number of false-positive reports.

Note: eventually named will have to stop treating such timeouts as due to RFC 1034 non compliance and start treating it as plain packet loss. Falsely classifying packet loss as due to RFC 1034 non compliance impacts on DNSSEC validation which requires EDNS for the DNSSEC records to be returned.


The catch-all. Many things still aren't classified into categories, and they all end up here.


Lame servers. These are misconfigurations in remote servers, discovered by BIND 9 when trying to query those servers during resolution.


Network operations.


The NOTIFY protocol.


NSID options received from upstream servers.


Specify where queries should be logged to.

At startup, specifying the category queries will also enable query logging unless querylog option has been specified.

The query log entry first reports a client object identifier in @0x<hexadecimal-number> format. Next, it reports the client's IP address and port number, and the query name, class and type. Next, it reports whether the Recursion Desired flag was set (+ if set, - if not set), whether the query was signed (S), whether EDNS was in use along with the EDNS version number (E(#)), whether TCP was used (T), whether DO (DNSSEC Ok) was set (D), whether CD (Checking Disabled) was set (C), whether a valid DNS Server COOKIE was received (V), and whether a DNS COOKIE option without a valid Server COOKIE was present (K). After this the destination address the query was sent to is reported. Finally, if any CLIENT-SUBNET option was present in the client query, it is included in square brackets in the format [ECS address/source/scope].

client ( query: IN AAAA +SE

client ::1#62537 ( query: IN AAAA -SE

(The first part of this log message, showing the client address/port number and query name, is repeated in all subsequent log messages related to the same query.)


Information about queries that resulted in some failure.


The start, periodic, and final notices of the rate limiting of a stream of responses are logged at info severity in this category. These messages include a hash value of the domain name of the response and the name itself, except when there is insufficient memory to record the name for the final notice The final notice is normally delayed until about one minute after rate limit stops. A lack of memory can hurry the final notice, in which case it starts with an asterisk (*). Various internal events are logged at debug 1 level and higher.

Rate limiting of individual requests is logged in the query-errors category.


DNS resolution, such as the recursive lookups performed on behalf of clients by a caching name server.


Information about errors in response policy zone files, rewritten responses, and at the highest debug levels, mere rewriting attempts.


Approval and denial of requests.


Whether or not a stale answer is used following a resolver failure.


Logs queries that have been terminated, either by dropping or responding with SERVFAIL, as a result of a fetchlimit quota being exceeded.


Logs trust-anchor-telemetry requests received by named.


Messages that named was unable to determine the class of or for which there was no matching view. A one line summary is also logged to the client category. This category is best sent to a file or stderr, by default it is sent to the null channel.


Dynamic updates.


Approval and denial of update requests.


Zone transfers the server is receiving.


Zone transfers the server is sending.


Loading of zones and creation of automatic empty zones.

The query-errors Category

The query-errors category is specifically intended for debugging purposes: To identify why and how specific queries result in responses which indicate an error. Messages of this category are therefore only logged with debug levels.

At the debug levels of 1 or higher, each response with the rcode of SERVFAIL is logged as follows:

client query failed (SERVFAIL) for at query.c:3880

This means an error resulting in SERVFAIL was detected at line 3880 of source file query.c. Log messages of this level will particularly help identify the cause of SERVFAIL for an authoritative server.

At the debug levels of 2 or higher, detailed context information of recursive resolutions that resulted in SERVFAIL is logged. The log message will look like as follows:

fetch completed at resolver.c:2970 for
in 30.000183: timed out/success [,

The first part before the colon shows that a recursive resolution for AAAA records of completed in 30.000183 seconds and the final result that led to the SERVFAIL was determined at line 2970 of source file resolver.c.

The following part shows the detected final result and the latest result of DNSSEC validation. The latter is always success when no validation attempt is made. In this example, this query resulted in SERVFAIL probably because all name servers are down or unreachable, leading to a timeout in 30 seconds. DNSSEC validation was probably not attempted.

The last part enclosed in square brackets shows statistics information collected for this particular resolution attempt. The domain field shows the deepest zone that the resolver reached; it is the zone where the error was finally detected. The meaning of the other fields is summarized in the following table.


The number of referrals the resolver received throughout the resolution process. In the above example this is 2, which are most likely com and


The number of cycles that the resolver tried remote servers at the domain zone. In each cycle the resolver sends one query (possibly resending it, depending on the response) to each known name server of the domain zone.


The number of queries the resolver sent at the domain zone.


The number of timeouts since the resolver received the last response.


The number of lame servers the resolver detected at the domain zone. A server is detected to be lame either by an invalid response or as a result of lookup in BIND9's address database (ADB), where lame servers are cached.


The number of erroneous results that the resolver encountered in sending queries at the domain zone. One common case is the remote server is unreachable and the resolver receives an ICMP unreachable error message.


The number of unexpected responses (other than lame) to queries sent by the resolver at the domain zone.


Failures in finding remote server addresses of the domain zone in the ADB. One common case of this is that the remote server's name does not have any address records.


Failures of resolving remote server addresses. This is a total number of failures throughout the resolution process.


Failures of DNSSEC validation. Validation failures are counted throughout the resolution process (not limited to the domain zone), but should only happen in domain.

At the debug levels of 3 or higher, the same messages as those at the debug 1 level are logged for other errors than SERVFAIL. Note that negative responses such as NXDOMAIN are not regarded as errors here.

At the debug levels of 4 or higher, the same messages as those at the debug 2 level are logged for other errors than SERVFAIL. Unlike the above case of level 3, messages are logged for negative responses. This is because any unexpected results can be difficult to debug in the recursion case.

masters Statement Grammar

masters string [ port integer ] [ dscp
    integer ] { ( masters | ipv4_address [
    port integer ] | ipv6_address [ port
    integer ] ) [ key string ]; ... };

masters Statement Definition and Usage

masters lists allow for a common set of masters to be easily used by multiple stub and slave zones in their masters or also-notify lists.

options Statement Grammar

This is the grammar of the options statement in the named.conf file:

options {
	allow-new-zones boolean;
	allow-notify { address_match_element; ... };
	allow-query { address_match_element; ... };
	allow-query-cache { address_match_element; ... };
	allow-query-cache-on { address_match_element; ... };
	allow-query-on { address_match_element; ... };
	allow-recursion { address_match_element; ... };
	allow-recursion-on { address_match_element; ... };
	allow-transfer { address_match_element; ... };
	allow-update { address_match_element; ... };
	allow-update-forwarding { address_match_element; ... };
	also-notify [ port integer ] [ dscp integer ] { ( masters |
	    ipv4_address [ port integer ] | ipv6_address [ port
	    integer ] ) [ key string ]; ... };
	alt-transfer-source ( ipv4_address | * ) [ port ( integer | * )
	    ] [ dscp integer ];
	alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer |
	    * ) ] [ dscp integer ];
	answer-cookie boolean;
	attach-cache string;
	auth-nxdomain boolean; // default changed
	auto-dnssec ( allow | maintain | off );
	automatic-interface-scan boolean;
	avoid-v4-udp-ports { portrange; ... };
	avoid-v6-udp-ports { portrange; ... };
	bindkeys-file quoted_string;
	blackhole { address_match_element; ... };
	cache-file quoted_string;
	catalog-zones { zone string [ default-masters [ port integer ]
	    [ dscp integer ] { ( masters | ipv4_address [ port
	    integer ] | ipv6_address [ port integer ] ) [ key
	    string ]; ... } ] [ zone-directory quoted_string ] [
	    in-memory boolean ] [ min-update-interval ttlval ]; ... };
	check-dup-records ( fail | warn | ignore );
	check-integrity boolean;
	check-mx ( fail | warn | ignore );
	check-mx-cname ( fail | warn | ignore );
	check-names ( primary | master |
	    secondary | slave | response ) (
	    fail | warn | ignore );
	check-sibling boolean;
	check-spf ( warn | ignore );
	check-srv-cname ( fail | warn | ignore );
	check-wildcard boolean;
	cleaning-interval integer;
	clients-per-query integer;
	cookie-algorithm ( aes | sha1 | sha256 | siphash24 );
	cookie-secret string;
	coresize ( default | unlimited | sizeval );
	datasize ( default | unlimited | sizeval );
	deny-answer-addresses { address_match_element; ... } [
	    except-from { string; ... } ];
	deny-answer-aliases { string; ... } [ except-from { string; ...
	    } ];
	dialup ( notify | notify-passive | passive | refresh | boolean );
	directory quoted_string;
	disable-algorithms string { string;
	    ... };
	disable-ds-digests string { string;
	    ... };
	disable-empty-zone string;
	dns64 netprefix {
		break-dnssec boolean;
		clients { address_match_element; ... };
		exclude { address_match_element; ... };
		mapped { address_match_element; ... };
		recursive-only boolean;
		suffix ipv6_address;
	dns64-contact string;
	dns64-server string;
	dnskey-sig-validity integer;
	dnsrps-enable boolean;
	dnsrps-options { unspecified-text };
	dnssec-accept-expired boolean;
	dnssec-dnskey-kskonly boolean;
	dnssec-enable boolean;
	dnssec-loadkeys-interval integer;
	dnssec-lookaside ( string trust-anchor
	    string | auto | no );
	dnssec-must-be-secure string boolean;
	dnssec-secure-to-insecure boolean;
	dnssec-update-mode ( maintain | no-resign );
	dnssec-validation ( yes | no | auto );
	dnstap { ( all | auth | client | forwarder |
	    resolver | update ) [ ( query | response ) ];
	    ... };
	dnstap-identity ( quoted_string | none |
	    hostname );
	dnstap-output ( file | unix ) quoted_string [
	    size ( unlimited | size ) ] [ versions (
	    unlimited | integer ) ] [ suffix ( increment
	    | timestamp ) ];
	dnstap-version ( quoted_string | none );
	dscp integer;
	dual-stack-servers [ port integer ] { ( quoted_string [ port
	    integer ] [ dscp integer ] | ipv4_address [ port
	    integer ] [ dscp integer ] | ipv6_address [ port
	    integer ] [ dscp integer ] ); ... };
	dump-file quoted_string;
	edns-udp-size integer;
	empty-contact string;
	empty-server string;
	empty-zones-enable boolean;
	fetch-quota-params integer fixedpoint fixedpoint fixedpoint;
	fetches-per-server integer [ ( drop | fail ) ];
	fetches-per-zone integer [ ( drop | fail ) ];
	files ( default | unlimited | sizeval );
	flush-zones-on-shutdown boolean;
	forward ( first | only );
	forwarders [ port integer ] [ dscp integer ] { ( ipv4_address
	    | ipv6_address ) [ port integer ] [ dscp integer ]; ... };
	fstrm-set-buffer-hint integer;
	fstrm-set-flush-timeout integer;
	fstrm-set-input-queue-size integer;
	fstrm-set-output-notify-threshold integer;
	fstrm-set-output-queue-model ( mpsc | spsc );
	fstrm-set-output-queue-size integer;
	fstrm-set-reopen-interval ttlval;
	geoip-directory ( quoted_string | none );
	glue-cache boolean;
	heartbeat-interval integer;
	hostname ( quoted_string | none );
	inline-signing boolean;
	interface-interval ttlval;
	ixfr-from-differences ( primary | master | secondary | slave |
	    boolean );
	keep-response-order { address_match_element; ... };
	key-directory quoted_string;
	lame-ttl ttlval;
	listen-on [ port integer ] [ dscp
	    integer ] {
	    address_match_element; ... };
	listen-on-v6 [ port integer ] [ dscp
	    integer ] {
	    address_match_element; ... };
	lmdb-mapsize sizeval;
	lock-file ( quoted_string | none );
	managed-keys-directory quoted_string;
	masterfile-format ( map | raw | text );
	masterfile-style ( full | relative );
	match-mapped-addresses boolean;
	max-cache-size ( default | unlimited | sizeval | percentage );
	max-cache-ttl ttlval;
	max-clients-per-query integer;
	max-journal-size ( default | unlimited | sizeval );
	max-ncache-ttl ttlval;
	max-records integer;
	max-recursion-depth integer;
	max-recursion-queries integer;
	max-refresh-time integer;
	max-retry-time integer;
	max-rsa-exponent-size integer;
	max-stale-ttl ttlval;
	max-transfer-idle-in integer;
	max-transfer-idle-out integer;
	max-transfer-time-in integer;
	max-transfer-time-out integer;
	max-udp-size integer;
	max-zone-ttl ( unlimited | ttlval );
	memstatistics boolean;
	memstatistics-file quoted_string;
	message-compression boolean;
	min-cache-ttl ttlval;
	min-ncache-ttl ttlval;
	min-refresh-time integer;
	min-retry-time integer;
	minimal-any boolean;
	minimal-responses ( no-auth | no-auth-recursive | boolean );
	multi-master boolean;
	new-zones-directory quoted_string;
	no-case-compress { address_match_element; ... };
	nocookie-udp-size integer;
	notify ( explicit | master-only | boolean );
	notify-delay integer;
	notify-rate integer;
	notify-source ( ipv4_address | * ) [ port ( integer | * ) ] [
	    dscp integer ];
	notify-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ]
	    [ dscp integer ];
	notify-to-soa boolean;
	nta-lifetime ttlval;
	nta-recheck ttlval;
	nxdomain-redirect string;
	pid-file ( quoted_string | none );
	port integer;
	preferred-glue string;
	prefetch integer [ integer ];
	provide-ixfr boolean;
	qname-minimization ( strict | relaxed | disabled | off );
	query-source ( ( [ address ] ( ipv4_address | * ) [ port (
	    integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ]
	    port ( integer | * ) ) ) [ dscp integer ];
	query-source-v6 ( ( [ address ] ( ipv6_address | * ) [ port (
	    integer | * ) ] ) | ( [ [ address ] ( ipv6_address | * ) ]
	    port ( integer | * ) ) ) [ dscp integer ];
	querylog boolean;
	random-device ( quoted_string | none );
	rate-limit {
		all-per-second integer;
		errors-per-second integer;
		exempt-clients { address_match_element; ... };
		ipv4-prefix-length integer;
		ipv6-prefix-length integer;
		log-only boolean;
		max-table-size integer;
		min-table-size integer;
		nodata-per-second integer;
		nxdomains-per-second integer;
		qps-scale integer;
		referrals-per-second integer;
		responses-per-second integer;
		slip integer;
		window integer;
	recursing-file quoted_string;
	recursion boolean;
	recursive-clients integer;
	request-expire boolean;
	request-ixfr boolean;
	request-nsid boolean;
	require-server-cookie boolean;
	reserved-sockets integer;
	resolver-nonbackoff-tries integer;
	resolver-query-timeout integer;
	resolver-retry-interval integer;
	response-padding { address_match_element; ... } block-size
	response-policy { zone string [ add-soa boolean ] [ log
	    boolean ] [ max-policy-ttl ttlval ] [ min-update-interval
	    ttlval ] [ policy ( cname | disabled | drop | given | no-op |
	    nodata | nxdomain | passthru | tcp-only quoted_string ) ] [
	    recursive-only boolean ] [ nsip-enable boolean ] [
	    nsdname-enable boolean ]; ... } [ add-soa boolean ] [
	    break-dnssec boolean ] [ max-policy-ttl ttlval ] [
	    min-update-interval ttlval ] [ min-ns-dots integer ] [
	    nsip-wait-recurse boolean ] [ qname-wait-recurse boolean ]
	    [ recursive-only boolean ] [ nsip-enable boolean ] [
	    nsdname-enable boolean ] [ dnsrps-enable boolean ] [
	    dnsrps-options { unspecified-text } ];
	root-delegation-only [ exclude { string; ... } ];
	root-key-sentinel boolean;
	rrset-order { [ class string ] [ type string ] [ name
	    quoted_string ] string string; ... };
	secroots-file quoted_string;
	send-cookie boolean;
	serial-query-rate integer;
	serial-update-method ( date | increment | unixtime );
	server-id ( quoted_string | none | hostname );
	servfail-ttl ttlval;
	session-keyalg string;
	session-keyfile ( quoted_string | none );
	session-keyname string;
	sig-signing-nodes integer;
	sig-signing-signatures integer;
	sig-signing-type integer;
	sig-validity-interval integer [ integer ];
	sortlist { address_match_element; ... };
	stacksize ( default | unlimited | sizeval );
	stale-answer-enable boolean;
	stale-answer-ttl ttlval;
	startup-notify-rate integer;
	statistics-file quoted_string;
	synth-from-dnssec boolean;
	tcp-advertised-timeout integer;
	tcp-clients integer;
	tcp-idle-timeout integer;
	tcp-initial-timeout integer;
	tcp-keepalive-timeout integer;
	tcp-listen-queue integer;
	tkey-dhkey quoted_string integer;
	tkey-domain quoted_string;
	tkey-gssapi-credential quoted_string;
	tkey-gssapi-keytab quoted_string;
	transfer-format ( many-answers | one-answer );
	transfer-message-size integer;
	transfer-source ( ipv4_address | * ) [ port ( integer | * ) ] [
	    dscp integer ];
	transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * )
	    ] [ dscp integer ];
	transfers-in integer;
	transfers-out integer;
	transfers-per-ns integer;
	trust-anchor-telemetry boolean; // experimental
	try-tcp-refresh boolean;
	update-check-ksk boolean;
	use-alt-transfer-source boolean;
	use-v4-udp-ports { portrange; ... };
	use-v6-udp-ports { portrange; ... };
	v6-bias integer;
	validate-except { string; ... };
	version ( quoted_string | none );
	zero-no-soa-ttl boolean;
	zero-no-soa-ttl-cache boolean;
	zone-statistics ( full | terse | none | boolean );

options Statement Definition and Usage

The options statement sets up global options to be used by BIND. This statement may appear only once in a configuration file. If there is no options statement, an options block with each option set to its default will be used.


Allows multiple views to share a single cache database. Each view has its own cache database by default, but if multiple views have the same operational policy for name resolution and caching, those views can share a single cache to save memory and possibly improve resolution efficiency by using this option.

The attach-cache option may also be specified in view statements, in which case it overrides the global attach-cache option.

The cache_name specifies the cache to be shared. When the named server configures views which are supposed to share a cache, it creates a cache with the specified name for the first view of these sharing views. The rest of the views will simply refer to the already created cache.

One common configuration to share a cache would be to allow all views to share a single cache. This can be done by specifying the attach-cache as a global option with an arbitrary name.

Another possible operation is to allow a subset of all views to share a cache while the others to retain their own caches. For example, if there are three views A, B, and C, and only A and B should share a cache, specify the attach-cache option as a view A (or B)'s option, referring to the other view name:

  view "A" {
    // this view has its own cache
  view "B" {
    // this view refers to A's cache
    attach-cache "A";
  view "C" {
    // this view has its own cache

Views that share a cache must have the same policy on configurable parameters that may affect caching. The current implementation requires the following configurable options be consistent among these views: check-names, cleaning-interval, dnssec-accept-expired, dnssec-validation, max-cache-ttl, max-ncache-ttl, max-stale-ttl, max-cache-size, and min-cache-ttl, min-ncache-ttl, zero-no-soa-ttl.

Note that there may be other parameters that may cause confusion if they are inconsistent for different views that share a single cache. For example, if these views define different sets of forwarders that can return different answers for the same question, sharing the answer does not make sense or could even be harmful. It is administrator's responsibility to ensure configuration differences in different views do not cause disruption with a shared cache.


The working directory of the server. Any non-absolute pathnames in the configuration file will be taken as relative to this directory. The default location for most server output files (e.g. is this directory. If a directory is not specified, the working directory defaults to `.', the directory from which the server was started. The directory specified should be an absolute path, and must be writable by the effective user ID of the named process.


dnstap is a fast, flexible method for capturing and logging DNS traffic. Developed by Robert Edmonds at Farsight Security, Inc., and supported by multiple DNS implementations, dnstap uses libfstrm (a lightweight high-speed framing library, see to send event payloads which are encoded using Protocol Buffers (libprotobuf-c, a mechanism for serializing structured data developed by Google, Inc.; see

To enable dnstap at compile time, the fstrm and protobuf-c libraries must be available, and BIND must be configured with --enable-dnstap.

The dnstap option is a bracketed list of message types to be logged. These may be set differently for each view. Supported types are client, auth, resolver, forwarder, and update. Specifying type all will cause all dnstap messages to be logged, regardless of type.

Each type may take an additional argument to indicate whether to log query messages or response messages; if not specified, both queries and responses are logged.

Example: To log all authoritative queries and responses, recursive client responses, and upstream queries sent by the resolver, use:

dnstap {
  client response;
  resolver query;

Logged dnstap messages can be parsed using the dnstap-read utility (see dnstap-read(1) for details).

For more information on dnstap, see

The fstrm library has a number of tunables that are exposed in named.conf, and can be modified if necessary to improve performance or prevent loss of data. These are:

  • fstrm-set-buffer-hint: The threshold number of bytes to accumulate in the output buffer before forcing a buffer flush. The minimum is 1024, the maximum is 65536, and the default is 8192.
  • fstrm-set-flush-timeout: The number of seconds to allow unflushed data to remain in the output buffer. The minimum is 1 second, the maximum is 600 seconds (10 minutes), and the default is 1 second.
  • fstrm-set-output-notify-threshold: The number of outstanding queue entries to allow on an input queue before waking the I/O thread. The minimum is 1 and the default is 32.
  • fstrm-set-output-queue-model: Controls the queuing semantics to use for queue objects. The default is mpsc (multiple producer, single consumer); the other option is spsc (single producer, single consumer).
  • fstrm-set-input-queue-size: The number of queue entries to allocate for each input queue. This value must be a power of 2. The minimum is 2, the maximum is 16384, and the default is 512.