22 June 2026 · 6 min read
Google Cloud DNS stores SPF, DKIM and DMARC records like any other DNS host, but three of its habits catch people out: TXT values must be wrapped in quotation marks, the name field adds your zone for you, and records in a private zone are invisible to the rest of the internet. This guide covers the console and gcloud steps for each record.
Cloud DNS is the DNS service inside Google Cloud. It is separate from Google Workspace and from the old Google Domains registrar, so only follow these steps if your domain's name servers point at a Cloud DNS zone.
Before you start: check Cloud DNS answers for your domain
A record only takes effect if the world queries the zone you are editing. Check two things:
- The zone's Visibility is Public. A private zone only answers inside your VPC networks, so a DMARC record there looks fine in the console while every mail server on the internet gets no answer.
- The name servers set at your registrar match the four
ns-cloud-...googledomains.comservers in the zone's NS record set.
The DNS record checker shows what public DNS returns, which is what receivers act on.
How the Cloud DNS record form works
In the Google Cloud console, open Cloud DNS, select your zone and click Add standard. The Create record set form has these fields:
- DNS name. Type only the part before your zone, such as
_dmarc. The zone name is already shown after the box, and the trailing dot is added for you. For a record at the root of the domain, leave the box empty: in Cloud DNS,@does not create a root record. - Resource record type.
TXTfor SPF, DMARC and key-based DKIM.CNAMEfor DKIM records that point at your email provider. - TTL and TTL unit. How long resolvers may cache the answer.
- The data field. Click Add item to add another value to the same record set.
Then click Create.
A Cloud DNS record set is one name plus one type, holding one or more values. That matters for SPF: the root of your domain can only have one TXT record set, so if one already exists (for a site verification token, say), edit it and add SPF as another item rather than trying to create a second set.
TXT quoting rules in Cloud DNS
Google's record types reference says to enclose each TXT string in quotation marks, and that each string can be at most 255 characters. Longer data is split into several quoted strings, which receivers join back together. For SPF, RFC 7208 says the strings are joined with no spaces added, so put the split after a space inside the first string:
"v=spf1 include:_spf.google.com include:servers.mcsv.net " "include:sendgrid.net ~all"The DNS record splitter produces correctly quoted 255-character strings from a long value.
Add the SPF record
- Add standard, leave DNS name empty, and choose
TXT. - Enter the SPF value in quotation marks.
- Set a TTL, for example 300 seconds while you are testing, and click Create.
For a domain that sends only through Google Workspace, Google's own value is:
"v=spf1 include:_spf.google.com ~all"Every service that sends as your domain goes in this one record. Two values that both start with v=spf1 make SPF return a permanent error, and so does a record that needs more than ten DNS lookups. Cloud DNS does not check SPF syntax, so run the SPF checker after publishing.
Add DKIM records
DKIM records live at <selector>._domainkey.example.com. Your email provider chooses the selector and tells you whether to publish a CNAME or a TXT record.
CNAME records, used by Microsoft 365, Amazon SES and most sending platforms:
- Add standard, and in DNS name type only the host part, for example
selector1._domainkey. If you paste the full name including your domain, the record becomesselector1._domainkey.example.com.example.com.and never resolves. - Choose
CNAMEand paste the target exactly as your provider gives it, ending with a dot. When Cloud DNS imports a zone file it treats any name without a trailing dot as relative to your zone, and the dot removes that ambiguity everywhere. - Do not put quotation marks around a CNAME target.
TXT records hold the public key itself:
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." "...IDAQAB"A 2048-bit key is longer than 255 characters, so it must be split into two or more quoted strings. The split can fall anywhere inside the p= value. Check each selector with the DKIM checker.
Add the DMARC record
- Add standard, type
_dmarcin DNS name, and chooseTXT. - Enter a monitoring policy in quotation marks, such as the one below.
- Click Create.
"v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"DMARC always lives at _dmarc, never at the root next to SPF. Publish exactly one DMARC record. Build the value with the DMARC generator, then confirm it with the DMARC checker.
The same records with gcloud
gcloud dns record-sets create _dmarc.example.com. \
--zone=my-zone --type=TXT --ttl=300 \
--rrdatas='"v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"'The single quotes stop your shell from removing the double quotes, so Cloud DNS receives one quoted string. For the root SPF record, use example.com. as the name.
--rrdatas is a comma-separated list, so a value that contains a comma, such as a DMARC record with two rua addresses, would be split into two records. Google's gcloud escaping rules let you choose another delimiter by starting the value with it between carets:
--rrdatas='^|^"v=DMARC1; p=none; rua=mailto:a@example.com,mailto:b@example.net"'For a DKIM CNAME, pass the target with its trailing dot and no quotation marks: --type=CNAME --rrdatas=selector1-example-com._domainkey.example.n-v1.dkim.mail.microsoft.
TTL while you change policy
Resolvers cache a record for its TTL, so a mistake on a record with a one-day TTL can linger for a day. Keep SPF and DMARC at a short TTL, such as 300 seconds, while you are changing them. Before editing a record that has a long TTL, lower the TTL first and wait for the old value to expire, then make the change. The DNS propagation checker shows when resolvers see the new value.
From p=none to p=reject
Publishing the records is the first step. Read the aggregate reports that arrive at your rua address, make sure every legitimate sender passes SPF or DKIM with alignment, then move to p=quarantine and later p=reject. The current DMARC standard, RFC 9989, removed the old pct= tag; to trial a stricter policy, add t=y. p=none vs quarantine vs reject explains each stage, and the same records on another host are covered in adding DMARC, SPF and DKIM on Azure DNS.
If you would rather not edit quoted TXT strings by hand, hosted DMARC publishes and stages the DMARC record for you, and hosted SPF keeps your SPF record under the ten-lookup limit as senders change.