[ DMARC & policy ]

Malformed DMARC records: inspect the exact value before naming the error

Review record boundaries, first-tag identification, separators, whitespace and duplicate names with precise fixtures, then distinguish syntax from conditional policy fallback.

By the EmailAuth research team · 6 min read

[ Key points ]

  • Preserve exact owner names, record boundaries and characters.
  • Separate version identification, tag grammar and policy fallback.
  • A syntax correction still needs actual message-route verification.
On this page

A plausible DMARC string can fail because it was published at the wrong name, divided into separate records or altered by an editor. It can also contain an invalid policy value that has a specific fallback rather than the generic error an operator expects.

Review the exact returned value in stages. Preserve the DNS representation and record boundaries first, then inspect identification, grammar and policy semantics. This approach makes the correction reviewable and avoids unnecessary policy changes.

Confirm the owner and record boundaries

Query the applicable _dmarc name for the actual From domain. Save the full TXT record set, authority, time and TTL. A value at the domain root does not satisfy the expected publication name.

A TXT resource record can contain several character strings. DMARC joins strings within that record in order before parsing under RFC 9989 §4.5. It does not join separate resource records into one policy.

For example, this is one synthetic zone-style record:

_dmarc.example.com. 300 IN TXT "v=DMARC1; " "p=none"

The quotes delimit the zone-file representation. Inspect what the DNS provider actually stores and returns before deciding that quotes are literal record content.

Identify the version first

Under RFC 9989 §4.7 and the inherited RFC 6376 §3.2 syntax, use the registered lower-case tag names and exact version value DMARC1. The v tag must appear first. A missing version, a different value or a version appearing only after another tag causes the record to be ignored under RFC 9989.

Do not rely on changing the case of tag names to produce an equivalent recognised tag. Values also have tag-specific requirements; the version value is explicitly case-sensitive.

This is different from the case behaviour of DNS names. Avoid extending a general DNS-name rule to the text inside a DMARC policy.

Inspect separators and whitespace precisely

Tag-value pairs use semicolons as separators. Commas have a different role inside a reporting destination list and cannot replace every semicolon in the record.

Whitespace is not universally forbidden. The inherited RFC 6376 §3.2 tag-value grammar permits whitespace around tag syntax, but that does not authorise spaces inside a token whose own value grammar forbids them.

A copy-and-paste operation can introduce typographic quotation marks, nonstandard punctuation or an unintended line break. Compare the exact stored characters against the grammar rather than repairing the value by sight. Retain both the original and proposed corrected form.

Use fixtures that name the processing stage

The following synthetic fixtures illustrate distinct problems and decisions. They are not live test results or a promise of identical diagnostic labels from every implementation.

  • Fixture at one owner name: v=DMARC1; p=none; rua=mailto:reports@example.com; Review finding: Explicit none policy and reporting request
  • Fixture at one owner name: p=none; v=DMARC1; Review finding: Version is not first; ignore this record
  • Fixture at one owner name: v=DMARC2; p=none; Review finding: Not the current defined version; ignore this record
  • Fixture at one owner name: v=DMARC1; p=invalid; rua=mailto:reports@example.com; Review finding: Apply the current conditional policy fallback
  • Fixture at one owner name: v=DMARC1; p=invalid; Review finding: No qualifying rua URI for that fallback
  • Fixture at one owner name: v=DMARC1; p=none; p=reject; Review finding: Duplicate tag name; repair the invalid tag-list rather than selecting one value
  • Fixture at one owner name: Two separate records each starting v=DMARC1; Review finding: Multiple policy candidates; inspect record-set filtering and discovery
  • Fixture at one owner name: v=DMARC1; p=none; xnote=example; Review finding: Unknown tag is ignored under the current rules

A custom unknown tag should not become part of the operational policy contract merely because a parser ignores it. Use documented fields and keep administrative notes in the change record.

Distinguish duplicate names from multiple records

A duplicate tag is a repeated name inside one tag-list. The inherited RFC 6376 §3.2 DKIM tag-value syntax prohibits duplicate names and treats that list as invalid. Do not assume the last p value overrides the first or combine two rua tags without a planned correction.

Multiple policy records are a different layer. Under RFC 9989 §4.10, current DNS tree-walk processing discards multiple DMARC policy records at one target. Discovery may then find another applicable policy. A fixture that tests only the first name has not established the complete receiver outcome.

Keep these findings separate in a bug report: exact record count, concatenated single-record value, duplicate names and subsequent discovery.

Apply current policy fallback without overgeneralising it

Under RFC 9989 §4.10.1, a missing or invalid p, or invalid sp or np, causes continued processing as p=none only if rua contains at least one syntactically valid reporting URI. Otherwise no DMARC processing applies to that message under those rules.

This condition does not validate every arbitrarily broken tag-list. A record ignored at version identification does not become usable just because it contains an address later. Apply the rules at the stage where they belong.

Under RFC 9990 §4, a syntactically valid reporting URI also does not prove external-destination authorisation, reachability or actual collection. The no-reports guide covers those separate dependencies.

Verify the approved correction

Make one coherent intended record set at the exact owner name. Review the defined tag rules in RFC 9989 §4.7, the registry reference in RFC 9989 §9.3 and the complete semantic change. Do not add another policy record as an override.

Save the configuration diff and the old value for investigation and recovery. Check authoritative answers after the change, compare relevant recursive views and account for cached earlier data. The record workflow joins those checks to representative mail testing.

Finally, send a controlled message through the actual application route. A syntactically valid policy does not prove that SPF or DKIM aligns with From. Keep the DNS correction and the sender's authentication evidence together, with separate findings where necessary.

The useful result is a precise explanation of the defect, its processing stage, the corrected value and the verified mail outcome. That is more durable than declaring every malformed-looking string a permanent error.

Keep the decision and evidence separate

For v=DMARC1; p=invalid with a valid rua URI, apply the stated conditional fallback only after the record reaches the relevant stage. Do not apply that repair rule to a version-rejected or duplicate-tag list. Keep the policy intent and actual message test as separate approval evidence. RFC 8767 §4 permits qualifying stale answers after TTL expiry; changing syntax does not instantly replace every cache. No parser, DNS or mail test was executed.

[ Takeaway ]

Preserve exact owner names, record boundaries and characters. Separate version identification, tag grammar and policy fallback. A syntax correction still needs actual message-route verification.

[ By role ]

What this means for you

Choose your role for practical next steps.

IT / Mail Admin

Diagnose in stages.

Record boundaries, identification, syntax and policy fallback need different checks.

Next steps

  1. Preserve complete DNS answers and exact characters.
  2. Use valid and deliberately invalid fixtures for the relevant rule.
  3. Retest the corrected record and actual message identities.

CISO / SecOps

Keep parser findings and assurance distinct.

A repaired string is one dependency in a maintained authentication service.

Next steps

  1. Record specification and implementation assumptions.
  2. Review reporting scope and delegated identities.
  3. Retain precise findings rather than one generic broken-status label.

Founder / Non-technical

Approve the intended policy, not a visually plausible string.

Small text edits can alter reporting, scope or how mail is assessed.

Next steps

  1. Require a readable configuration diff.
  2. Assign the policy and application owners.
  3. Verify the important communication after the edit.

[ FAQs ]

Frequently asked questions

Does any space in a DMARC record make it invalid?

No. The tag-value grammar permits whitespace in specified positions. Inspect the exact location and each tag's value grammar rather than applying a blanket no-spaces rule.

RFC 6376 §3.2 RFC 9989 §4.7

Must v=DMARC1 be first?

Yes. RFC 9989 requires the v tag first and the exact value DMARC1. A missing, misplaced or different version causes that record to be ignored.

RFC 9989 §4.7

Can I replace semicolons with commas?

No. Semicolons separate tag-value pairs. Commas can separate reporting URIs within their defined list; those roles are different.

RFC 6376 §3.2 RFC 9989 §4.7

Are quotes visible in a DNS lookup always part of the stored DMARC value?

No. They can be presentation delimiters for TXT character strings. Inspect the provider and returned record representation before deciding what the actual content contains.

RFC 1035 §5.1 RFC 1035 §3.3.14

What happens when the same tag appears twice?

The inherited tag-value syntax prohibits duplicate names and invalidates that list. Correct the intended single value instead of relying on first-value or last-value behaviour.

RFC 6376 §3.2 RFC 9989 §4.7

Does an unknown tag automatically invalidate the policy?

No. RFC 9989 requires unknown tags to be ignored. That does not make arbitrary syntax errors or invalid recognised values equivalent to harmless unknown data.

RFC 9989 §4.7

Does invalid p always mean the same permerror result?

No. Current discovery defines conditional none processing with a syntactically valid rua URI for missing or invalid p, or invalid sp or np. Other failures must be assessed at their own stage.

RFC 9989 §4.10.1

What should a human reviewer see before approving the repair?

Provide exact before-and-after values, owner name and record boundaries, the identified grammar or discovery rule, and DNS and representative message verification.

[ Sources ]

Sources

  1. RFC 9989

    Sections §4.5 · §4.7 · §4.10 · §4.10.1 · §5.3.5 · §9.3 · §3.2.6

  2. RFC 6376

    Sections §3.2

  3. RFC 1035

    Sections §3.3.14 · §5.1

  4. RFC 9990

    Sections §4

  5. RFC 8767

    Sections §4

[ Glossary ]

Glossary

DMARC Policy Record
A DNS TXT record enabling validation and expressing handling preferences and optional reporting requests for applicable domains.

RFC 9989 §3.2.6

Tag-value list
A semicolon-separated syntax with defined whitespace positions and no duplicate tag names.

RFC 6376 §3.2

Enterprise provenance

Why top financial institutions and governments retired their email security dashboards.

Traditional email authentication platforms sell you a dashboard and ask your engineers to do the labour. In high-stakes environments, manual oversight means delayed enforcement, configuration drift and unmonitored shadow domains.

EmailAuth is the agentic email provenance platform. Our agents enforce p=reject, keep third-party senders aligned and move your domains to full RFC 9989 compliance, the new DMARC standard,, with human-in-the-loop auditability.

Governments Large enterprises Tier-1 financial institutions

SaaS · Dedicated tenancy · Air-gapped on-prem · BYOK encryption

Knowledge Base