Skip to content

Zone management

Record builders

Build valid SPF, DMARC, CAA, DKIM, Microsoft 365, and LOC DNS records with guided forms, input checks, and optional SPF flattening in the zone editor.

6 min read

On this page

The SPF builder, DMARC record generator, and CAA record builder turn structured inputs into draft records alongside DKIM, Microsoft 365, and LOC builders. A builder edits only your unsaved draft: you still review its output, save, preview, and push before any provider changes.

Use a builder#

Open the builder

Open Zones → select a zone → Records → Use a builder. Pick one of the nine builder cards.

Generate records

Complete the fields and select Preview records. List fields accept one value per line. A duration accepts seconds or a suffix such as 5m, 1h, or 1d.

Review the result

Read Check these when warnings appear, then inspect Records to add. Select Regenerate after changing an input.

Put the result in the draft

Select Add to draft. A generated record set replaces a draft record set with the same name and type. Select Save changes, then follow Preview and push.

A blank TTL uses the zone's Default TTL; when neither is set, the DNSControl-compatible default is 300 seconds. Label is relative to the zone, and @ means the zone apex.

How to use the SPF builder#

SPF_BUILDER creates one TXT record and can resolve and flatten selected include: or redirect= targets. When flattening is enabled, it also keeps the unmodified policy at Raw record label. Test a policy below, then read how to diagnose and fix the SPF 10-lookup limit.

SPF lookup counter

Count top-level mechanisms that consume SPF's ten-lookup evaluation budget.

Paste one TXT value beginning with v=spf1. Nothing leaves this browser.

Top-level budget

3/ 10

7 top-level slots remain.

3 of 10 top-level DNS lookups are used.

include, a, mx, ptr, exists, and redirect each cost one lookup. ip4, ip6, and all do not.

Terms in this record

Top level only
  • include:_spf.google.com+1 lookup
  • include:sendgrid.net+1 lookup
  • mx+1 lookup
  • ~allNo lookup

Includes can nest. Every lookup inside an included SPF record also counts during evaluation, so this top-level count can be lower than the real total.

FieldWhat it does
LabelOwner of the published TXT record; default @.
SPF partsRequired, one token per line. Defaults to v=spf1 and ~all; at least two elements are required.
Includes to flattenInclude domains to replace recursively; * selects every include.
Overflow label patternSplits a long policy into linked TXT records. It must contain %d, for example _spf%d.
Overhead for the first recordReserves this many characters when calculating the first split.
Raw record labelOwner for the original policy when flattening; default _rawspf.
Max TXT sizeMaximum policy length before splitting; default 255.
Keep ignored redirectsRetains redirects that would otherwise be removed after a flattened policy reaches an all mechanism.
TTLTTL for both the published and raw record sets.

Suppose _spf.example.net resolves to v=spf1 ip4:192.0.2.0/24 -all. With SPF parts set to v=spf1, include:_spf.example.net, -all, and Includes to flatten set to *, the result is:

text
@        300 TXT "v=spf1 ip4:192.0.2.0/24 -all"
_rawspf  300 TXT "v=spf1 include:_spf.example.net -all"
dnsconfig.js
SPF_BUILDER({
  label: "@",
  parts: ["v=spf1", "include:_spf.example.net", "-all"],
  flatten: ["*"],
  ttl: 300,
})

The parser accepts a, mx, include, redirect, exists, ptr, ip4, ip6, and a terminal all, including qualifiers. Resolution errors, multiple or missing included SPF records, include loops, and unsupported mechanisms leave the record unflattened and produce a warning. The builder counts nested DNS lookups after resolution, adds one lookup for each overflow link, and warns above the RFC 7208 limit of 10. A split pattern without %d also warns and leaves the policy unsplit. See Lint and validation for the checks that continue to run on the draft.

DMARC record generator#

DMARC_BUILDER emits one TXT record at _dmarc or _dmarc.<label>.

FieldWhat it does
LabelDomain under which _dmarc is created; default @.
Versionv= value; default DMARC1. Another value is allowed but warns that receivers will ignore it.
Policy (p=)Required: none, quarantine, or reject.
Subdomain policy (sp=) / Non-existent subdomain policy (np=)Optional policies with the same three choices.
SPF alignment (aspf=) / DKIM alignment (adkim=)r for relaxed or s for strict.
Percent (pct=, deprecated)Integer from 0 through 100; emits a deprecation warning.
Aggregate report URIs (rua=) / Failure report URIs (ruf=)One URI per line; each needs a URI scheme and cannot contain whitespace, commas, semicolons, or !.
Failure options (fo=)Any selected 0, 1, d, or s, joined with :. Emitted only when ruf is present; 0 alone is omitted.
Failure format (rf=, deprecated)Colon-separated alphanumeric or hyphenated tokens; requires ruf and warns.
Report interval (ri=, deprecated)Duration converted to seconds; warns.
Public suffix domain (psd=)y, n, or u.
Test mode (t=)y or n.
TTLTXT record TTL.
text
_dmarc  300 TXT "v=DMARC1; p=reject; sp=quarantine; adkim=s; aspf=r; rua=mailto:dmarc@example.com; ruf=mailto:fail@example.com; fo=1"
dnsconfig.js
DMARC_BUILDER({
  policy: "reject",
  subdomainPolicy: "quarantine",
  alignmentDKIM: "s",
  alignmentSPF: "r",
  rua: ["mailto:dmarc@example.com"],
  ruf: ["mailto:fail@example.com"],
  failureOptions: "1",
})

Invalid policies, alignments, percentages, URIs, failure options, formats, public-suffix values, or test-mode values stop generation.

CAA record builder#

CAA_BUILDER combines all values at one owner into a CAA record set. A checked critical field uses flag 128; otherwise it uses 0.

FieldWhat it does
LabelCAA owner; default @.
Violation report URI (iodef)Optional iodef value. iodef critical controls its flag.
Allowed CAs (issue)One issue value per line. Enter none to generate ";". issue critical controls the flag.
Allowed wildcard CAs (issuewild)issuewild values; none generates ";". issuewild critical controls the flag.
Allowed VMC CAs (issuevmc)issuevmc values. issuevmc critical controls the flag.
Allowed S/MIME CAs (issuemail)issuemail values. issuemail critical controls the flag.
TTLTTL for the CAA record set.
text
@  600 CAA 0 issue "letsencrypt.org"
@  600 CAA 0 issuewild ";"
@  600 CAA 128 iodef "mailto:security@example.com"
dnsconfig.js
CAA_BUILDER({
  label: "@",
  issue: ["letsencrypt.org"],
  issuewild: ["none"],
  iodef: "mailto:security@example.com",
  iodef_critical: true,
  ttl: 600,
})

At least one of issue, issuewild, issuevmc, or issuemail must contain a value; iodef alone is not enough.

DKIM builder#

DKIM_BUILDER creates a TXT record at <selector>._domainkey, optionally under another label.

FieldWhat it does
SelectorRequired first label. It cannot be empty.
Public key (base64)p= value; blank produces an empty p=.
LabelOptional suffix after _domainkey; default @.
VersionMust be DKIM1.
Key type (k=)rsa or ed25519.
Hash algorithms (h=)sha1 and/or sha256 for RSA; only sha256 for Ed25519.
Service types (s=)* and/or email.
Flags (t=)y and/or s.
Note (n=)Human-readable note, encoded as DKIM quoted-printable where needed.
TTLTXT record TTL.
text
mail._domainkey  300 TXT "v=DKIM1; h=sha256; k=rsa; p=MIGfExample; s=email; t=s"
dnsconfig.js
DKIM_BUILDER({
  selector: "mail",
  pubkey: "MIGfExample",
  keytype: "rsa",
  hashtypes: ["sha256"],
  servicetypes: ["email"],
  flags: ["s"],
})

An unsupported version, key type, hash for that key type, service, or flag stops generation.

Microsoft 365 builder#

M365_BUILDER generates Microsoft 365 service records. It uses the zone default TTL because this form has no TTL field.

FieldWhat it does
Microsoft 365 domainRequired domain used to derive targets and the domain GUID.
LabelOwner for MX and optional SPF only; default @.
Initial domain (*.onmicrosoft.com)Required while DKIM CNAMEs is on.
Domain GUIDPrefix for mail and DKIM targets. If omitted, dots in the domain become hyphens; domains already containing a hyphen require an explicit value.
MX recordOn by default; priority 0 to <guid>.mail.protection.outlook.com.
Autodiscover CNAMEOn by default; creates autodiscover.
DKIM CNAMEsOn by default; creates selectors 1 and 2 using the initial domain.
Skype for Business / TeamsAdds lyncdiscover, sip, _sip._tls, and _sipfederationtls._tcp.
Mobile device management / Intune enrollment (same records as MDM)Either adds enterpriseregistration and enterpriseenrollment; enabling both does not duplicate them.
SPF TXT (DNSMigrator extension)Adds v=spf1 include:spf.protection.outlook.com -all.
text
@                    300 MX    0 example-com.mail.protection.outlook.com.
autodiscover         300 CNAME autodiscover.outlook.com.
selector1._domainkey 300 CNAME selector1-example-com._domainkey.example.onmicrosoft.com.
selector2._domainkey 300 CNAME selector2-example-com._domainkey.example.onmicrosoft.com.
dnsconfig.js
M365_BUILDER("example.com", {
  initialDomain: "example.onmicrosoft.com",
})

Turn off unwanted defaults before previewing. The builder validates the two DKIM prerequisites described above; it does not contact Microsoft to discover your tenant values.

LOC builders#

All four LOC builders emit one LOC record with altitude defaulting to 0 meters and size, horizontal precision, and vertical precision set to 0.00m. Label defaults to @; Altitude (m) and TTL are optional.

Decimal degrees#

Latitude (decimal degrees) and Longitude (decimal degrees) are required. Negative values become south and west.

text
white-house  300 LOC 38 53 51.940 N 77 02 11.580 W 19m 0.00m 0.00m 0.00m
dnsconfig.js
LOC_BUILDER_DD({ label: "white-house", x: 38.89775977858357, y: -77.03655125982903, alt: 19 })

Degrees and decimal minutes#

Coordinates is required and must contain latitude with N or S and longitude with E or W.

text
@  300 LOC 25 14 24.000 S 153 09 0.000 E 3m 0.00m 0.00m 0.00m
dnsconfig.js
LOC_BUILDER_DMM_STR({ str: "25.24°S 153.15°E", alt: 3 })

Degrees, minutes, and seconds#

Coordinates accepts typographic symbols, ASCII quotes, or letter separators.

text
opera  300 LOC 33 51 31.000 S 151 12 51.000 E 4m 0.00m 0.00m 0.00m
dnsconfig.js
LOC_BUILDER_DMS_STR({ label: "opera", str: "33°51′31″S 151°12′51″E", alt: 4 })

Any coordinate format#

Coordinates is required. This builder tries decimal-minutes parsing first, then degrees-minutes-seconds parsing.

text
geyser  300 LOC 44 27 38.000 N 110 49 41.000 W 2240m 0.00m 0.00m 0.00m
dnsconfig.js
LOC_BUILDER_STR({ label: "geyser", str: "44.46046°N 110.82815°W", alt: 2240 })

Malformed coordinates or latitude/longitude outside DNS LOC bounds stop generation. The decimal-degrees implementation also rejects the exact coordinate 0, 0; use one of the string LOC builders for that point. Review provider support in Record types before pushing a LOC record.