A report can show failed DMARC alignment without showing the handling requested by the domain owner. That is not automatically contradictory. The receiver evaluates authentication and then makes a handling decision using DMARC and its own policy. Read those stages separately before reporting that a domain passed or that enforcement is broken.
Start with the report context
References: RFC 9990 §3.3.
Preserve the reporting organization, report identifier, time window and policy_published block. Use the policy observed in that report rather than today's DNS alone. RFC 9990 section 3.3 describes policy changes within a reporting period: a report may represent the final configuration even though some messages encountered an earlier one. That limits what one policy label proves about every row.
Read the report's format and namespace before interpreting vocabulary. Current RFC 9990 and historical RFC 7489 reports can coexist in an ingestion system. Do not silently translate unfamiliar values into success or discard the original payload after normalization.
Separate three layers
References: RFC 9990 §3.1.1.9, RFC 9990 §3.1.1.11, RFC 9990 §3.1.6.
The auth_results block contains SPF and DKIM results uninterpreted with respect to DMARC. A signature can pass under a domain that does not align with Header From. The policy_evaluated SPF and DKIM values describe the DMARC-related evaluations, including alignment. Disposition describes the result of applying DMARC policy, rather than independently proving either authentication mechanism passed.
Inspect every reported override reason and any comment. RFC 9990 defines local_policy, mailing_list, other, policy_test_mode and trusted_forwarder reasons. They describe why handling differed; they do not rewrite failed SPF or DKIM into passing aligned authentication. Treat a receiver's mailing-list classification as reported context, not proof that your organization approved that list.
Annotate an illustrative row
References: RFC 9989 §5.3.5, RFC 9989 §5.4.
Assume applicable valid policy and completed checks. A synthetic report records p=reject for brand.example. Its raw SPF result passes for relay.example, which is unrelated to brand.example; no aligned DKIM signature passes. Both policy_evaluated mechanisms fail, but disposition is none with reason trusted_forwarder. The correct interpretation is that DMARC failed and the receiver exempted the message from the requested action because it anticipated forwarding-related authentication failure.
This example describes fields, not a complete XML fixture or an observed customer event. It does not prove inbox delivery. The receiver may apply spam or other controls independently, and aggregate reporting does not provide a per-message folder-placement receipt.
Decide what to investigate
For a known business route, compare the reported identity with a controlled received message and the sending configuration. For an unknown route, retain an unresolved classification while looking for an owner. An override reason can help prioritize that investigation, but it is not permission to add an IP to SPF or approve a provider.
Close the analysis with four statements: what policy was reported, which aligned authentication path passed or failed, what handling was reported, and what evidence is still missing. Count message volume using the row count and preserve reporter and period. Avoid equating a count of rows with a count of messages or presenting one receiver's local exception as a universal delivery rule.
Inspect an annotated field fixture
References: RFC 9990 §3.1.1.14, RFC 9990 §3.1.1.8.
The following is a synthetic field projection, not a complete schema-valid XML report. Its stated period is fixture day 0 (Unix seconds 0–86399), not an observed reporting day.
- Field: policy_published/domain, p; Fixture value: brand.example, reject; Interpretation: Requested policy used by this fixture
- Field: identifiers/header_from; Fixture value: brand.example; Interpretation: Author identity for alignment
- Field: row/source_ip, count; Fixture value: 192.0.2.40, 12; Interpretation: Connecting address and messages represented
- Field: auth_results/spf/domain, result; Fixture value: bounces.vendor.example, pass; Interpretation: Raw success under an unrelated domain
- Field: auth_results/dkim/domain, result; Fixture value: vendor.example, pass; Interpretation: Raw success without author alignment
- Field: policy_evaluated/spf, dkim; Fixture value: fail, fail; Interpretation: Neither qualifying aligned path passes
- Field: policy_evaluated/disposition; Fixture value: none; Interpretation: Requested rejection was not applied
- Field: policy_evaluated/reason/type; Fixture value: trusted_forwarder; Interpretation: Receiver-reported exception
Under the fixture's explicit strict alignment mode, neither authenticated domain equals brand.example. The supplied local identity exercise reproduces that failed authentication decision independently of the disposition value. The reason object contains a required type and an optional comment; neither field changes the alignment result. The next investigation is route corroboration for the twelve messages, not an automatic SPF addition.
Keep the exercise within scope
The examples are partial field projections, not schema-valid reports or measured traffic. Local checks use explicitly supplied authentication results and organizational relationships; they do not perform DNS discovery, SPF evaluation, cryptographic verification, report ingestion or receiver delivery tests. Preserve the original report and trusted message evidence before making a production change.