15 June 2026 · 17 min read
Gandi is a registrar that also runs its own authoritative DNS, and the place where most people publish email authentication on Gandi is the LiveDNS editor inside the modern web console. It is a clean, no-nonsense interface, which is mostly a good thing. The trouble is that Gandi's editor is quite literal: it shows you something close to raw zone-file syntax, it expects an @ for the root in a way some other panels hide, it has a separate "as a text" view that experienced users prefer and beginners corrupt, and it has a TTL column with its own minimum. None of that is hard once you know it, but every one of those details has its own way of silently producing a record that looks fine and fails at the receiver. This guide is specific to Gandi LiveDNS and the records you need for DMARC, SPF and DKIM. It is not a generic "what is DMARC" primer; if you want that grounding first, read What is DMARC, What is SPF and What is DKIM, then come back here to actually publish.
Everything below assumes Gandi is authoritative for your domain, which means your domain is using Gandi's LiveDNS nameservers (the ns-*.gandi.net set) and not an external DNS provider. If you bought the domain at Gandi but pointed the nameservers somewhere else (Cloudflare, Route 53, your host), the records in this guide must go on that other provider instead, because that is where the internet actually looks. Confirm where your DNS lives before you start: a quick lookup with the DNS record checker tells you which nameservers are answering for your domain.
First, confirm you are editing LiveDNS and not the legacy "Classic" DNS
Gandi has historically had two DNS systems: the older "Classic" DNS and the newer LiveDNS. Almost every domain is on LiveDNS now, and LiveDNS is what the current console gives you, but it is worth a glance because the record-name conventions differ slightly and people who migrated old domains sometimes land in the wrong place.
In the Gandi console, open your domain, then go to the DNS records tab (Gandi labels it under the domain's management page). If you see a table with Type, Name, TTL and Value columns and an Add button, you are in LiveDNS. That is the right place for DMARC, SPF and DKIM.
Before you change anything, take a baseline so you can tell later whether you improved things or broke them. Check your current DMARC policy with the DMARC checker, your sending record with the SPF checker, and any existing signatures with the DKIM checker. Knowing the "before" state is what stops you chasing a problem that was already there before you touched the zone.
The three records and exactly where they live on Gandi
The single most common publishing mistake on any DNS host is putting the right value at the wrong name. Gandi's editor makes the name explicit, which helps, as long as you know what to type. Fix these targets in your head first.
- SPF is one TXT record at the root of your domain. In Gandi's Name field you enter
@, which represents the bare domain (example.com). The value begins withv=spf1. You must have exactly one SPF record; two is a permanent error that no receiver forgives. - DMARC is one TXT record at the host
_dmarc. In the Name field you enter_dmarc(just that, with the leading underscore), and Gandi serves it as_dmarc.example.com. The value begins withv=DMARC1. - DKIM is published per selector at
selector._domainkey. In the Name field you enter something likedefault._domainkeyorgoogle._domainkeyors1._domainkey, givingselector._domainkey.example.com. The value is either a long TXT public key, or a CNAME pointing at your provider's hosted key, depending on the platform.
Two rules apply to every record you add in the Gandi LiveDNS editor, and breaking either is the cause of most "I added it but the checker says nothing is there" tickets.
- Enter the host part only in Name, never the full domain. Gandi appends the zone for you. If you type
_dmarc.example.cominto the Name field, Gandi creates_dmarc.example.com.example.com, which resolves to nothing useful. Type only_dmarc,@, orselector._domainkey. This is the same trap on every host, but it bites especially on Gandi because the editor will not correct you. - Use
@for the root, not a blank field. Some panels accept an empty Name to mean the apex. Gandi expects an explicit@. For SPF, the Name is@.
Adding a record in the Gandi LiveDNS editor, step by step
The mechanics are the same for all three record types. In the DNS records view:
- Click Add (sometimes shown as Add record or a plus button at the top of the table).
- Choose the Type:
TXTfor SPF and DMARC, and eitherTXTorCNAMEfor DKIM depending on your sending platform. - In Name, enter the host part only:
@,_dmarc, orselector._domainkey. - Set the TTL. Gandi defaults to 10800 seconds (three hours). For authentication records you are about to verify and possibly tweak, set this lower, for example 3600 (one hour) or Gandi's minimum of 300 seconds (five minutes) while you are still working. More on TTL below.
- In Value, paste the record value. For a TXT record, Gandi's form generally wants the value wrapped in double quotes:
"v=DMARC1; p=none; ...". This is the one place Gandi differs visibly from hosts that strip quotes for you. More on quoting below. - Click Create (or Save / Add).
Concrete examples, with the values shown exactly as the receiver needs to see them.
DMARC, starting at monitoring policy. Type TXT, Name _dmarc, Value:
"v=DMARC1; p=none; rua=mailto:dmarc-rua@example.com; fo=1; adkim=s; aspf=s"
SPF for a domain sending through Google Workspace plus one marketing tool. Type TXT, Name @, Value:
"v=spf1 include:_spf.google.com include:servers.mcsv.net -all"
DKIM as a CNAME (the common case for Google Workspace, Amazon SES, Postmark, and most platforms that host the key for you). Type CNAME, Name google._domainkey, Value points at the host your provider gives you, for example:
google._domainkey.example.com. CNAME google._domainkey.example.com.dkim.example-provider.net.
DKIM as a TXT public key (when you generate the key yourself). Type TXT, Name s1._domainkey, Value is the full key string in quotes:
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
If you do not yet have the DMARC value worked out, build a valid one with the DMARC generator and assemble SPF carefully so you start from a syntactically correct string rather than guessing at the tags.
Quoting on Gandi: the detail that breaks the most records
Gandi's LiveDNS is closer to raw zone-file syntax than the "friendly" editors at some other registrars, and TXT values in zone files are quoted strings. In practice the Gandi form is forgiving and will usually accept a value with or without surrounding quotes, but the safe, predictable habit is to wrap the whole TXT value in a single pair of double quotes, exactly as shown in the examples above.
Two failure modes to avoid:
- Stray inner quotes. Do not put quotes around individual tags.
"v=DMARC1"; "p=none"is wrong; you want one pair of quotes around the entire string:"v=DMARC1; p=none; ...". Inner quotes get stored literally and corrupt the value. - A smart-quote from a word processor. If you copy a record out of an email, a PDF, or a document, you can pick up "curly" typographic quotes (
"and") instead of straight ASCII quotes ("). Gandi treats a curly quote as a literal character inside the value, and the record fails to parse. Always type straight quotes, or paste from a plain-text source.
After you save any TXT record on Gandi, confirm it parses, do not just trust that the form accepted it. Run the matching checker: the DMARC checker for the _dmarc record, the SPF checker for the root, and the DKIM checker for each selector. "Gandi saved it" only means the record exists; it does not mean the value is valid.
The "edit the zone as a text file" view: power, and a sharp edge
Gandi LiveDNS offers a mode where you edit the entire zone as plain text in BIND-style zone-file format, rather than one record at a time in the table. Experienced administrators love this because you can paste a block of records and review the whole zone at a glance. It is also the fastest way to wreck a working zone if you are not careful, because there is no per-field validation as you type and a single misplaced character can invalidate the line.
If you use the text view, a few rules:
- Names that are not fully qualified get the zone appended. A line beginning
_dmarcmeans_dmarc.example.com. A line beginning_dmarc.example.com.with a trailing dot is treated as already fully qualified. Mixing these up is how you create a doubled-up name. Be consistent: use the short host form (_dmarc,@,selector._domainkey) without a trailing dot. - Each record needs its TTL, type and quoted value. A typical line reads
_dmarc 3600 IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-rua@example.com". Forgetting the quotes around the value, or putting the TTL in the wrong column, breaks the line. - You are replacing the whole zone when you save. Unlike adding a single record in the table, saving the text view writes the entire block. Before you do, copy the current text out into a note, so you have an exact rollback if the new version misbehaves.
For most people adding three or four authentication records, the table editor is safer. Reserve the text view for when you are confident with zone-file syntax and want to review everything at once.
TXT chunking: long DKIM keys on Gandi
A 2048-bit DKIM public key in a TXT record is longer than 255 characters, and a single DNS character-string is capped at 255 bytes. This is the classic place where a DKIM record "exists" but fails, because the key got mangled at the 255-character boundary.
In Gandi's table editor, paste the entire v=DKIM1; k=rsa; p=... value as one continuous quoted string in the Value field. Gandi's LiveDNS handles a value longer than 255 characters by storing it as a correctly chunked multi-string TXT record; you do not normally need to split it by hand in the table view.
In the text (zone-file) view, the convention is different and more manual. There, a TXT value longer than 255 characters is written as several adjacent quoted strings, which DNS concatenates back together:
s1._domainkey 3600 IN TXT ( "v=DKIM1; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...first 255 chars..."
"...remaining characters of the key..." )
The split point between the strings does not matter to DNS as long as the strings, concatenated in order with nothing between them, reproduce the original key exactly. The trap is accidentally inserting a space or a newline character inside the actual key data when you split it, which silently corrupts it. If you are pasting a long key, prefer the table editor where Gandi does the chunking for you, and if you must split it manually, a tool like the DNS record splitter gives you correctly bounded chunks.
Whichever route you take, verify afterwards with the DKIM checker. A truncated or mis-split paste is the single most common cause of a DKIM record that resolves but fails verification. For why the chunk boundary matters and how selectors work, see DKIM selectors explained.
CNAME records for DKIM on Gandi, and the trailing-dot question
Many providers (Google Workspace, Amazon SES, Postmark, and others) hand you DKIM as a CNAME that points at a key they host, so you never see the key itself. On Gandi you add these as ordinary CNAME records, and there is no proxy toggle to worry about, unlike Cloudflare. Two Gandi-flavoured details:
- The target should be fully qualified with a trailing dot. In the table editor, enter the host part in Name (
google._domainkey) and the provider's target in Value. If you are in the text view, the target on the right side of a CNAME should end with a dot, for example...dkim.amazonses.com., to mark it as a fully qualified name. A missing trailing dot in the text view can cause Gandi to append your own zone to the target, producing a CNAME that points at...dkim.amazonses.com.example.com, which resolves to nothing. - Do not also create a TXT at the same name. A name can be a CNAME or have other records, but not both. If your provider gives you a CNAME for
selector._domainkey, do not additionally paste a TXT key at the sameselector._domainkey. Pick the one your provider told you to use.
The same trailing-dot care applies to any other CNAME involved in authentication, such as a custom MAIL FROM / return-path host or an MTA-STS policy host. Get the trailing dot right and the CNAME resolves cleanly; get it wrong and the lookup dead-ends.
SPF on Gandi: one record, and the auto-added Gandi mail record
SPF has two pitfalls on Gandi beyond the universal "exactly one record" rule.
First, the editor will let you create two TXT records that both start with v=spf1, and it will not warn you. Two SPF records is a permerror, treated as a hard failure by every receiver. The frequent cause on Gandi specifically: you use Gandi's own mailbox / email service, which publishes an SPF record (often including _mailcust.gandi.net), and then you add a second SPF for your other senders. Now you have two, and SPF breaks. The fix is to merge into a single SPF record that includes everything:
"v=spf1 include:_mailcust.gandi.net include:_spf.google.com -all"
After editing, confirm there is exactly one SPF record with the SPF checker.
Second, Gandi does not flatten SPF or count your DNS lookups for you. SPF allows a maximum of ten DNS-resolving mechanisms (include, a, mx, ptr, exists, redirect). Stack up Gandi mail, Google Workspace, a CRM and a marketing tool and you can quietly cross ten, producing a permerror regardless of how correct each include is on its own. Gandi gives you no signal that this has happened. The remedy is flattening, resolving the includes down to IP ranges so the record stays under the limit, which Gandi does not do natively. Read SPF PermError: too many DNS lookups and Fix SPF PermError; our hosted SPF flattening keeps a single flat record under the limit and updates it automatically as your senders change.
A syntax note Gandi is perfectly happy with but people still get wrong: use -all (hard fail) for a locked-down domain, and ~all (soft fail) only while you are still discovering which services send as you. Gandi stores either faithfully; the choice only matters at the receiver.
DMARC on Gandi: start at monitoring, then tighten
The DMARC record is a single TXT at _dmarc. Start in monitoring mode so you collect data before any of your mail is affected:
"v=DMARC1; p=none; rua=mailto:dmarc-rua@example.com; fo=1; adkim=s; aspf=s"
A few details, some Gandi-specific and some DMARC-specific:
- Put a real, monitored mailbox in
rua. Aggregate reports (RUA) are XML, sent daily by receivers, and are how you learn which sources send as your domain before you enforce. Gandi does not parse them for you. Feed them into the DMARC report analyzer, or use our emailed monitoring so the XML becomes a readable picture instead of an unread attachment. - External RUA destinations need authorisation. If the mailbox in
ruais on a different domain from the one you are protecting, that other domain must publish a_report._dmarcauthorisation record. If you keep RUA on the same domain, you skip this. It is a DMARC rule, not a Gandi one, and Gandi will not warn you either way. - Move through the policy stages deliberately.
p=none, thenp=quarantine, thenp=reject, usingpctand the subdomain policyspas controls along the way. The pacing and reasoning are in DMARC policy: none vs quarantine vs reject, and the alignment tagsadkimandaspfare covered in DMARC alignment explained.
Do not jump to p=reject on day one. The entire point of starting at none on Gandi, or anywhere, is to see your real sending sources in the reports first, fix any that fail alignment, then enforce. Rushing this is how legitimate mail gets quarantined or rejected. The staged route is laid out in Reach p=reject without breaking email.
TTL on Gandi: lower it before a change, not after
TTL (time to live) is how long resolvers cache a record. Gandi exposes TTL as an explicit value in seconds on every record, with a default of 10800 (three hours) and a minimum of 300 (five minutes).
- For records you are actively setting up and verifying, use a low TTL such as 3600 or 300. That way, if you got something wrong and need to fix it, the bad value is not cached around the internet for three hours.
- Lower the TTL before a planned change, not at the same moment. TTL only governs how long the old value stays cached. If you intend to rotate a DKIM key or tighten SPF and you want a fast cutover, drop the TTL first, wait for the old TTL to expire, then make the change. Lowering it at the instant you change the record does nothing for the value resolvers already hold.
- Once a record is stable, you can raise the TTL again. A longer TTL (back to 10800, or higher) reduces lookup load and is fine for a settled SPF or DMARC record you do not expect to touch. Keep DKIM TTLs shorter if you rotate keys regularly.
- "Saved on Gandi" is not "live everywhere". Even with a five-minute TTL, a resolver that fetched the old value four minutes ago under a longer TTL holds it until its own cache expires. Check propagation with the DNS record checker rather than assuming the change is global the moment Gandi accepts it.
This matters most for DKIM key rotation, where you overlap an old and a new selector to avoid a signing gap. The overlap technique is covered in DKIM key rotation.
Editing safely on Gandi
Gandi LiveDNS overwrites a record when you edit and save it, and there is no per-record one-click undo. Practical habits that save you:
- Copy the current value into a note before editing, especially for SPF and DKIM, so you can restore the exact old string if the change misbehaves.
- Export the zone first. Gandi lets you view and copy the full zone in the text view; take a copy before a round of authentication changes so you have a complete rollback.
- Change one record at a time and verify before moving on. Add or edit DKIM, confirm it with the DKIM checker; edit SPF, confirm with the SPF checker; then touch DMARC and confirm with the DMARC checker. Batching all three and then discovering a failure leaves you guessing which one broke.
Doing it at scale: the Gandi LiveDNS API
If you manage many domains, the Gandi web console is not the only route. LiveDNS exposes the same operations over a REST API, which matters for authentication records because they are easy to template and audit as code.
- A
POST(to create) orPUT(to replace) against the LiveDNS records endpoint for a zone, with a JSON body specifyingrrset_type(such asTXTorCNAME),rrset_name(the host part,@/_dmarc/selector._domainkey),rrset_ttl, andrrset_values(an array of strings), creates or updates a record. - For TXT values the array entries are the quoted strings, so a long DKIM key is naturally expressed as multiple chunks in the
rrset_valuesarray, which is the cleanest way to handle keys over 255 characters programmatically.
Whichever route you use, the underlying rules from this guide do not change: one SPF TXT at the root, one DMARC TXT at _dmarc, DKIM per selector, CNAME targets fully qualified, and long DKIM keys chunked correctly.
A quick end-to-end checklist
Run through this after publishing on Gandi:
- Gandi LiveDNS is the authoritative DNS for the domain (nameservers are
ns-*.gandi.net), and you are in the DNS records (LiveDNS) editor, not a stale Classic zone. - Exactly one SPF TXT at
@, under ten DNS lookups, ending in-allor~allas intended, with Gandi's own mail include merged in if you use Gandi email. - One DMARC TXT at
_dmarc, starting atp=none, with a realruamailbox you actually read. - DKIM published per sending platform: CNAME targets fully qualified with a trailing dot, or TXT keys pasted whole and correctly chunked.
- TXT values wrapped in a single pair of straight (not curly) double quotes.
- TTL set low (300 to 3600) while you are setting up, raised again once stable.
- Everything verified by lookup, not by the editor's confirmation: DMARC checker, SPF checker, DKIM checker, and the DNS record checker for propagation.
The takeaway
Gandi LiveDNS is a tidy, honest DNS editor that does most of what you need without fuss: it chunks long TXT values in the table view, it gives you explicit TTL control, and it offers a full zone-file view when you want one. What it does not do is think about email authentication for you. It will let you publish two SPF records (very easily, because Gandi's own mail service adds one), accept a curly quote that corrupts your DMARC string, append your zone to a CNAME that is missing a trailing dot, or sail past the ten-lookup SPF limit, all without a single warning. The discipline that makes Gandi safe is the same on every host: right type, right name (host part only, @ for the root), one SPF, straight quotes, fully qualified CNAME targets, monitor first with p=none, and verify by lookup rather than trusting the "saved" message.
When you are ready to move from "the records exist" to "the records are correct and enforced", the staged path from p=none to p=reject is the real work, and it is exactly what we automate. See hosted DMARC, hosted SPF and hosted DKIM for the done-for-you route, or start free by pointing the DMARC checker at your domain and turning on emailed monitoring so any future change to these Gandi records pages you the moment it happens.