Skip to content

Migrations

BIND zone files

Import or export BIND zone files for DNS migration. Learn supported directives, TTL and owner rules, TXT handling, ignored DNSSEC data, and CLI workflows.

6 min read

On this page

A BIND zone file migration in DNSMigrator can use a file as the source, download translated records, or normalize files in the web tools and CLI. The parser supports a deliberate subset centered on $ORIGIN and $TTL, and reports or skips data it cannot represent instead of following other directives or preserving provider-only behavior.

How a BIND zone file migration works#

If you still need the source file, follow the provider-specific steps in How to export a DNS zone file before validating it here.

Validate the export

Open the zone-file validator and paste the provider or server export. Fix parse errors before using it as a migration source, especially missing origin, unknown types, and unsupported directives.

Choose Zone file as the source

Open Migrations → New migration. Under Where is the zone now?, choose Zone file, then paste into Zone file export. The panel shows the parsed record-set count, zone name, and how many lines could not be read.

Choose a connected destination

Pick an active destination under Where is it going? and select Create preview. File-to-file migration is disabled here; use the zone translator or CLI instead.

Review skipped and translated data

Parse errors do not necessarily reject the whole migration. If at least one record and a zone name can be found, preview continues and Activity reports how many zone-file lines were skipped. Review record statuses before apply.

To use a file as the destination, start from a connected provider and choose Zone file under Where is it going? The preview is free. Select Download zone file; nothing is applied to a provider.

The same Download zone file action is available on any migration with a preview. It serializes the translated target for that migration’s selected destination, not a raw source backup.

Minimal accepted file#

Use an explicit, fully qualified origin and a default TTL:

example.com.zone
$ORIGIN example.com.
$TTL 1h

@ IN SOA ns1.example.net. hostmaster.example.com. (
  2026092701 ; serial
  7200       ; refresh
  3600       ; retry
  1209600    ; expire
  300        ; negative cache
)
@                 IN NS    ns1.example.net.
@                 IN NS    ns2.example.net.
@          300    IN A     192.0.2.10
www               IN CNAME @
@                 IN MX    10 mail.example.net.
@                 IN TXT   "v=spf1 include:_spf.example.net -all"
selector._domainkey IN TXT ( "v=DKIM1; k=rsa; p=first-part"
                             "second-part" )
_sip._tcp          IN SRV   10 5 5060 sip.example.com.

Paste a file into the explainer to decode owners, TTLs, record types, and fields line by line. The BIND zone file format guide explains the underlying syntax in more detail.

BIND zone file explainer

Resolve owner names, inherited TTLs, record meanings, and individual RDATA fields in your browser.

BIND parsing runs locally; pasted zone data is not uploaded.

3 records explained for example.com..

3 records parsed for example.com.

Select any record to inspect its absolute owner name, effective TTL, purpose, and fields.

Record-by-record explanation

3 total
  1. SOAexample.com.1 hour · 3,600 seconds
    Absolute name
    example.com.
    Effective TTL
    1 hour (3,600 seconds)
    Type meaning
    Defines the zone's primary server, serial, timers, and negative-cache TTL.

    Fields

    Primary nameserver
    ns1.example.net.
    Responsible mailbox
    hostmaster.example.com.
    Serial
    2026092701
    Refresh
    7200
    Retry
    3600
    Expire
    1209600
    Negative cache TTL
    300
  2. NSexample.com.1 hour · 3,600 seconds
    Absolute name
    example.com.
    Effective TTL
    1 hour (3,600 seconds)
    Type meaning
    Delegates the zone or name to an authoritative nameserver.

    Fields

    Nameserver
    ns1.example.net.
  3. CNAMEwww.example.com.1 hour · 3,600 seconds
    Absolute name
    www.example.com.
    Effective TTL
    1 hour (3,600 seconds)
    Type meaning
    Aliases this name to another canonical name.

    Fields

    Target
    example.com.

Semicolons begin comments outside quoted strings. Parentheses join physical lines into one logical record. A line that begins with whitespace inherits the previous owner. Relative owner names are resolved under $ORIGIN; @ means the origin.

The parser can infer an origin from an absolute SOA owner when no $ORIGIN appeared yet. The CLI also accepts --origin <domain>. For predictable files, prefer an explicit $ORIGIN.

Supported directives#

DirectiveBehavior
$ORIGIN name.Sets the origin after lowercasing it. Use an ASCII or already-punycode name.
$TTL durationSets the default. Plain seconds and combined s, m, h, d, and w units are accepted, such as 1h30m.
$GENERATERejected. Materialize the generated records before pasting the file.
$INCLUDERejected. Paste the included file’s content into one input instead.
Any other $... directiveRejected with the same unsupported-directive message.

Unsupported directives produce a line-numbered error and are not executed. Expand generated records and paste included content into one reviewed file before validation.

Supported and ignored record types#

The parser accepts these types:

GroupTypes
Common address and namingA, AAAA, CNAME, ALIAS, DNAME, NS, PTR
Mail and textMX, TXT, SPF, RP
Service and policySRV, CAA, NAPTR, URI, HTTPS, SVCB
SecurityDS, DNSKEY, TLSA, SSHFP, CERT, OPENPGPKEY, SMIMEA
OtherSOA, LOC, DHCID

RRSIG, NSEC, NSEC3, NSEC3PARAM, CDS, and CDNSKEY are silently ignored by the BIND parser. DNSKEY is parsed, but migration translation marks it Managed because the destination signer supplies its own key. An unknown type, including an unlisted TYPE#### presentation, is reported as an error and skipped.

Support in the parser does not imply support at every destination. The translation engine checks the selected provider’s API catalog after parsing. For example, a valid TLSA record can still be Unsupported at a destination whose adapter does not declare TLSA. Compare providers under Supported providers.

TTL and owner rules#

For each record, effective TTL is selected in this order:

  1. A TTL written on that record.
  2. The current $TTL default.
  3. The last explicit per-record TTL.
  4. 3,600 seconds.

If there was no $TTL, parsing an SOA can set the default from its minimum field for later records. TTLs normalize to nonnegative integers in the canonical model and are later clamped to destination limits. See Translation rules.

Classes IN, CH, HS, and CS are recognized in the record preamble, but the canonical record model does not retain a class. DNSMigrator’s migration output is written as IN; do not use this workflow to preserve non-IN zone semantics.

The parser qualifies relative RDATA hostnames for CNAME, NS, PTR, ALIAS, DNAME, RP, MX, SRV, and SOA. Use fully qualified names with a trailing dot in other structured RDATA, including HTTPS/SVCB targets, to avoid ambiguity.

TXT strings#

Adjacent quoted strings form one logical TXT or SPF value. Parsing removes presentation quotes and joins the character strings. Serialization escapes backslashes and quotes, then splits one logical value into quoted segments of at most 255 characters:

text
selector._domainkey 300 IN TXT "first logical segment" "continued segment"

That split does not create multiple TXT records. The destination’s separate maximum logical-value length is still enforced; over-limit values become Unsupported instead of being truncated. Read TXT and SPF translation and Move DNS without losing email before moving long DKIM keys.

Errors and limits#

A web migration source is limited to 2,000,000 UTF-8 bytes by the service. Files above that limit are rejected as larger than 2 MB. The parser reports one-based source line numbers; whole-file errors such as oversize input use line 0.

Reported conditions include:

  • No owner name or no usable origin.
  • Missing type or record data.
  • Unknown record type.
  • Invalid $TTL values.
  • Unterminated quoted strings.
  • Unclosed parentheses.
  • Unsupported directives such as $INCLUDE.

The parser can return valid records and errors together. The migration workflow proceeds if it has a zone name and at least one record, so “preview ready” does not mean every line was accepted. Use --strict in the CLI or fix every validator finding when silent omission would be unsafe.

Serialization and loss#

Downloaded files start with $ORIGIN, $TTL 3600, and then sorted records with explicit per-record TTLs. TXT and SPF data is quoted. A header records the zone, selected destination, generation time, and the fact that unsupported records were omitted.

Provider aliases with no ordinary values cannot be represented faithfully in a zone file. The serializer writes a comment such as:

text
; @ A alias → d111111abcdef8.cloudfront.net. (alias records can't be expressed in a zone file)

That comment is not a working record. Likewise, proxy flags, routing policies, redirect rules, health checks, and other provider metadata are not BIND records. Prefer a provider-specific destination preview when preserving those features matters.

DNSSEC and provider features#

Do not copy source RRSIG, denial-of-existence chains, or DNSKEY material to a managed destination. The new provider signs with its own key, and the parent DS must be changed in the order described by DNSSEC transitions.

A BIND file carries DNS presentation data, not provider intent. Use an API connection when you need proxy state, provider-resource aliases, routing policy, redirect rules, or other settings that the file cannot represent.

CLI workflows#

The open-source CLI reads local files or - for standard input and never asks for provider credentials:

Normalize a BIND file
npx dnsmigrator export example.com.zone --format bind --out normalized.zone
Translate for a provider and save a JSON report
npx dnsmigrator translate example.com.zone \
  --to cloudflare \
  --out cloudflare.zone \
  --report translation.json \
  --strict
Compare two complete files
npx dnsmigrator diff before.zone after.zone --strict

export can produce bind, json, or DNSControl dnsconfig output. translate applies provider limits and appends unsupported source rows as comments after the generated zone, unlike the web download, which only states that unsupported rows were omitted. diff ignores SOA, DNSKEY, and apex NS because hosts manage them.

Use --origin example.com for a file without $ORIGIN, --json for machine-readable command output, and the CLI command reference for all flags.

BIND zone file questions#

What is a BIND zone file?
A BIND zone file is a text representation of DNS records, directives, owners, TTLs, and RDATA. DNSMigrator reads common BIND presentation syntax into its canonical record-set model.
Can DNSMigrator import a zone file that has errors?
It can return valid records and line-specific errors together, and a web migration can continue when it finds a zone name and at least one record. Fix every skipped line before relying on the preview, because a ready preview does not mean the complete file was accepted.
Which BIND directives are supported?
The parser supports $ORIGIN and $TTL. It rejects $INCLUDE, $GENERATE, and other directives, so expand or combine their records into one reviewed input first.
Does a zone file preserve proxying, aliases, and routing policies?
Not completely. Provider proxy flags, resource aliases, health checks, routing policies, and similar metadata are not ordinary BIND records and can be omitted or reduced to comments, so review the translation report before cutover.
Should DNSSEC signing records be copied in a zone file migration?
No. RRSIG and denial-chain records are ignored, while DNSKEY is treated as provider managed. Let the destination sign with its own key and change the parent DS through the DNSSEC cutover sequence.