Il record è giusto. L’hai controllato tre volte, un validatore online ti dà ragione, e la casella su cui hai puntato il tag rua= è vuota da una settimana.

Quasi tutti gli elenchi di cause che si trovano in giro sono disordinati, ed è l’unica cosa che un elenco del genere non può permettersi. Le verifiche hanno una sequenza naturale — ognuna dà senso alla successiva — e farle alla rinfusa significa dimostrare due volte la stessa cosa mentre la causa vera aspetta più in basso. Qui sotto c’è la sequenza. Prima ci sono due domande, perché per una buona parte di chi legge la risposta è che non si è rotto niente.

Due domande che possono chiudere la faccenda subito

Sono passate 48 ore?

I report aggregati non vengono emessi man mano che la posta viaggia. Ogni report copre un periodo di rilevazione, e RFC 9990 (§3.1.1.4) dice che quel periodo di norma coincide con una giornata UTC che comincia alle 00:00. La generazione e l’invio avvengono dopo che il periodo si è chiuso.

Quindi: se hai pubblicato martedì alle 16:00, il primo periodo che contiene il tuo record si chiude alle 00:00 UTC di mercoledì, e il report viene costruito e spedito qualche tempo dopo. Ventiquattro-quarantotto ore sono l’attesa normale, e i grandi riceventi si distribuiscono dentro quella finestra.

Due cose la allungano:

  • La cache del DNS. Se il nome _dmarc.example.com prima non esisteva, i resolver hanno messo in cache la sua assenza, non solo il suo contenuto. La cache negativa (RFC 2308) dura un tempo che deriva dal record SOA della zona, e un ricevente che ha guardato un’ora prima della tua pubblicazione non tornerà a guardare finché non scade. Controlla il minimum del tuo SOA prima di dare per scontato che qualcosa non funzioni.
  • Non puoi chiedere di andare più in fretta. Il tag ri= serviva a chiedere un intervallo di rilevazione più corto. RFC 9989 lo ha rimosso (Appendice C.5.2) e il registro IANA oggi lo classifica come historic. Pubblicare ri=3600 non ottiene niente: è un tag sconosciuto, e i tag sconosciuti vengono ignorati.

Il dominio spedisce davvero posta?

Un ricevente scopre che vuoi i report solo quando interroga la tua policy, e interroga la tua policy solo quando gli è arrivato un messaggio con il tuo dominio nel campo From: (RFC 9990 §3.4).

Niente posta, nessuna interrogazione, nessun report. Se il dominio è parcheggiato, o serve solo un sito web, o l’hai registrato il mese scorso e non ha ancora spedito nulla, il silenzio è l’esito corretto e nessun lavoro sul DNS lo cambierà. Un dominio che manda una manciata di messaggi al giorno è la versione attenuata dello stesso caso: riceverai report solo dai riceventi che hanno visto la tua posta e che gestiscono un programma di reporting, quindi una settimana magra non dimostra che il record sia sbagliato.

Se hai superato entrambe le domande, si scende lungo l’elenco.

Le sei cause, nell’ordine in cui vanno verificate

  1. Non c’è nessun record DMARC dove i riceventi lo cercano.
  2. Il record c’è, ma i riceventi lo scartano — quasi sempre un punto e virgola mancante.
  3. Il record è valido e non ha il tag rua=, oppure ne ha uno inutilizzabile.
  4. Il rua= è valido e non è il tuo — i report esistono, e vanno altrove.
  5. È troppo presto — se ne è parlato sopra.
  6. Stanno arrivando — e il problema è a valle.

Un comando solo risolve le prime quattro:

dig +short TXT _dmarc.example.com

1. Nessun record dove i riceventi lo cercano

La ricerca della policy parte dal nome che si ottiene anteponendo _dmarc al dominio scritto nel campo From: (RFC 9989 §4.10.1). Non l’apice, non www, non un CNAME verso la pagina commerciale del fornitore.

L’errore che genera più confusione lo produce il pannello DNS che aggiunge la zona per conto tuo. Hai scritto _dmarc.example.com nel campo nome, il pannello ha appeso .example.com, e il record adesso vive su _dmarc.example.com.example.com, dove nessuno guarderà mai. Il dig qui sopra non restituisce niente e il pannello continua a mostrarti un record che sembra perfetto. Credi al dig, non al pannello.

Ce n’è una versione più insidiosa. Se la posta parte da un sottodominio — From: noreply@mail.example.com — la ricerca guarda prima _dmarc.mail.example.com, e solo se lì non trova un record valido risale verso il dominio organizzativo (RFC 9989 §4.10). Entrambi gli esiti sono normali. Quello che conta per la tua dashboard vuota è che nel secondo caso il record che si applica è quello del dominio padre, e i report di quella posta vanno al rua del padre. Tienilo da parte se stai monitorando un sottodominio.

2. Il record c’è e i riceventi lo scartano

Tre modi in cui un record pubblicato viene buttato via prima che qualcuno arrivi a leggere il tuo rua:

Più di un record. Se un’interrogazione restituisce più record DMARC per lo stesso nome, vengono scartati tutti (RFC 9989 §4.10). È il classico strascico di un cambio di fornitore: il record vecchio non è mai stato cancellato e quello nuovo gli è stato messo accanto. dig +short li mostra entrambi. Due record corretti sono peggio di uno.

v= non è il primo, o non è esattamente DMARC1. Il tag di versione deve venire per primo, e il suo valore distingue maiuscole e minuscole. Se manca, se non è in testa o se è scritto diversamente, l’intero record va ignorato (RFC 9989 §4.7). v=dmarc1 non è un record DMARC.

Un punto e virgola mancante. Questo merita una sezione a sé, perché è invisibile e per come fallisce.

Un carattere: il punto e virgola mancante

Questi due record differiscono per un solo ;:

v=DMARC1; p=none rua=mailto:dmarc@example.com
v=DMARC1; p=none; rua=mailto:dmarc@example.com

Aperti nel pannello del DNS sono indistinguibili. Il primo non ti porta nessun report, ed ecco il meccanismo, perché non è quello che quasi tutti immaginano.

La grammatica di RFC 9989 §4.8 definisce il valore di un tag come qualunque carattere stampabile tranne il punto e virgola. Lo spazio rientra. Anche = rientra. Un ricevente che analizza il primo record non si ferma allo spazio: legge il valore di p come none rua=mailto:dmarc@example.com.

Adesso sono vere due cose insieme, ed è la seconda quella che fa male:

  • p ha un valore che non è none, quarantinereject, quindi non è valido;
  • nel record non c’è più nessun tag rua — è stato inghiottito dentro il valore di p.

RFC 9989 §4.10.1 tratta con indulgenza un p non valido, ma l’indulgenza ha una condizione. Se nel record c’è un tag rua con almeno un URI sintatticamente valido, il ricevente si comporta come se il record dicesse p=none e tira dritto — e il reporting sopravvive. Altrimenti «non applica alcuna elaborazione DMARC al messaggio».

Il punto e virgola mancante cancella esattamente il tag che avrebbe salvato la situazione. È per questo che questo refuso è silenzioso invece che rumoroso: non indebolisce la policy, ti toglie i report.

Lo stesso errore in altra forma, meno frequente, è un record con i tag in ordine sbagliato — p=none; v=DMARC1; rua=… — che cade sulla regola della versione vista sopra.

E il rovescio rassicurante, così non ci passi un pomeriggio: un frammento estraneo che non sia una coppia tag=valore non è fatale. RFC 9989 §4.8 dice che gli errori di sintassi nel resto del record vengono scartati in favore dei valori di default, oppure ignorati. Sciatto, da ripulire, ma non è il motivo per cui la tua dashboard è vuota.

3. Nessun rua= utilizzabile

Il tag è facoltativo per lo standard, e la sua assenza non lascia margini: senza rua i riceventi non devono generare report aggregati per quel dominio (RFC 9989 §4.7). Un record può essere impeccabile, imporre p=reject, e non dirti niente.

Tre modi in cui il tag c’è ma non serve a nulla:

  • Un indirizzo al posto di un URI. rua=dmarc@example.com non è un URI di reporting DMARC: un URI richiede uno schema. Va scritto rua=mailto:dmarc@example.com. È una dimenticanza facile da fare e difficile da vedere, perché a un lettore umano un indirizzo senza schema sembra del tutto ragionevole.
  • Solo https:. I riceventi sono obbligati a supportare mailto:; il supporto a qualunque altro schema è facoltativo, e gli URI con schemi non supportati devono essere ignorati (RFC 9989 §4.7). Un rua solo HTTPS è una scommessa, ricevente per ricevente.
  • Il vecchio limite di dimensione. Il suffisso !10m oggi è sintassi obsoleta, e chi genera i report è invitato a ignorarlo (RFC 9989 §4.8). Innocuo se c’è già, inutile da aggiungere.

4. Il rua= è valido, e non è il tuo

È la causa che sopravvive a tutte le verifiche precedenti, ed è quella che quasi nessuno va a cercare.

Un validatore di sintassi ti confermerà che rua=mailto:dmarc@reports.fornitore.example è un URI di reporting ben formato, perché lo è. Quello che nessun validatore può sapere è se quell’indirizzo sia tuo. Lo sai solo tu. Così il record supera ogni controllo, lo strumento che stai pagando resta vuoto, e da nessuna parte compare un errore — perché dal punto di vista del protocollo non c’è niente che non va. I report vengono generati, puntuali, tutti i giorni. Vanno da un’altra parte.

Da dove arriva, di solito, quell’altro indirizzo:

  • un fornitore DMARC precedente, dopo la scadenza dell’abbonamento — disdire un contratto non modifica il tuo DNS;
  • l’agenzia o l’MSP che ha configurato il dominio anni fa, che puntava al proprio account di aggregazione;
  • una casella interna su un sistema di posta che nel frattempo è stato dismesso.

La verifica consiste nel leggere l’elenco con i propri occhi, invece di fidarsi di una spunta verde. Lancia il dig di prima e leggi il valore di rua= per quello che è: una lista di destinazioni separate da virgola. Su ogni voce fatti una domanda sola: chi riceve posta a quell’indirizzo, oggi? Se per una non sai rispondere, l’hai trovata.

Due cose da sapere prima di mettere mano al record:

Essere uno fra tanti è del tutto normale, quindi la correzione di solito è aggiungere, non sostituire. Ogni destinazione valida dell’elenco riceve la propria copia; non esiste un destinatario principale. Se stai passando da uno strumento a un altro, tienili accesi entrambi per una settimana e confronta, poi togli il vecchio.

Se stai monitorando un sottodominio, controlla anche il padre. Per la risalita descritta nella causa 1, la posta che parte da un sottodominio privo di un proprio record _dmarc ricade sotto il record del dominio organizzativo — quindi i suoi report arrivano al rua del padre mentre la dashboard del sottodominio resta vuota. Non c’è niente di sbagliato nella configurazione: stai guardando lo scaffale sbagliato.

Due cause che non stanno nel record

La destinazione è su un altro dominio e non ha acconsentito

Se l’indirizzo rua sta sotto un dominio organizzativo diverso da quello che pubblica la policy, i riceventi devono prima accertarsi che la destinazione sia d’accordo (RFC 9990 §4). Il motivo è evidente appena lo si dice: senza quel controllo chiunque potrebbe pubblicare un record che dirotta una valanga di report su una vittima.

La verifica è un’interrogazione DNS che fa il ricevente. Prende l’host dal tuo URI rua, gli antepone _report._dmarc, e antepone ancora il dominio da cui è arrivata la policy. Quindi una policy su example.com che chiede rua=mailto:dmarc@reports.example.net produce una richiesta TXT per

example.com._report._dmarc.reports.example.net

e la risposta deve leggersi come un record DMARC con v=DMARC1 in testa. Se quel record non c’è, l’URI deve essere ignorato dal ricevente che sta generando il report (RFC 9990 §4). Di nuovo silenzio, senza che si sia rotto niente in nessuno dei posti in cui ti verrebbe da guardare.

Tre conseguenze pratiche:

  • Il record va nella zona della destinazione, non nella tua. Se i report vanno a un servizio di terze parti, tocca a loro pubblicarlo, e la maggior parte usa una wildcard — *._report._dmarc.<loro dominio> — che copre tutti i clienti in un colpo solo. Se invece i report vanno a una casella su un secondo dominio tuo, nessuno lo pubblicherà al posto tuo.
  • Stesso dominio organizzativo, nessuna verifica. Una policy su _dmarc.mail.example.com che spedisce a dmarc@example.com non attiva affatto questo controllo.
  • L’ultima parola ce l’ha la destinazione. Il record di consenso può a sua volta contenere un rua, che sovrascrive quello della tua policy, vincolato allo stesso host (RFC 9990 §4). È raro, ma è un altro modo legittimo in cui i report finiscono dove non hai deciso tu.

È la casella che se li mangia

Un report è una normalissima email con un allegato: un file XML che dovrebbe essere compresso con gzip, trasportato come application/gzip oppure text/xml, con un nome costruito nella forma ricevente!dominio-policy!timestamp-inizio!timestamp-fine.xml.gz (RFC 9990 §3.5.2).

L’oggetto è fissato dallo standard, e questo ti dà una cosa da cercare:

Subject: Report Domain: example.com
    Submitter: mx.example.net
    Report-ID: 1755820800-example.com@example.net

Cerca Report Domain: in tutta la casella — spam, quarantena e archivio compresi. Se saltano fuori dei messaggi, tutto quello che c’è scritto sopra è a posto e il problema è a valle. Se non salta fuori niente da nessuna parte, le cause precedenti sono ancora in gioco.

Che cosa se li mangia, grosso modo in ordine di frequenza: le policy sugli allegati che bloccano o rimuovono i file compressi; una regola che li archivia in una cartella che nessuno apre; una casella condivisa la cui quarantena non guarda nessuno; e un indirizzo rua che in realtà non accetta posta, il che produce bounce che tu non vedi mai, perché tornano al ricevente e non a te.

Un dettaglio che ti risparmia una discussione con chi gestisce la posta: il traffico dei report è a sua volta autenticato con DMARC — RFC 9990 §3.5.2 richiede che questi flussi producano un pass allineato. Quando i report finiscono in quarantena si tratta di una scelta del filtro locale, non di un problema di autenticazione.

Arrivano, e la dashboard è comunque vuota

Se i messaggi li hai trovati, quello che resta sta tutto a valle della consegna.

Stai guardando il dominio sbagliato. Viene generato un report distinto per ogni dominio della policy incontrato nel periodo (RFC 9990 §3.1). Apri uno degli XML e leggi policy_published/domain: è lo scaffale su cui quei dati sono stati archiviati. Se dice example.com e tu stai guardando mail.example.com, torna alla causa 4.

I duplicati sono stati tolti, ed è giusto così. Quando chi genera un report lo rispedisce deve riutilizzare il nome di file originale, e il Report-ID esiste proprio perché chi lo riceve possa riconoscere e ignorare i duplicati (RFC 9990 §3.5.2). Un report arrivato due volte che compare una volta sola è il sistema che funziona.

L’importazione ha una sua cadenza. I report vengono raccolti e analizzati a lotti, non nell’istante in cui atterrano. Se il primo è arrivato venti minuti fa, dagli un’ora prima di aprire una segnalazione.


Mentre aspetti il primo report non sei costretto ad aspettare per sapere qualcosa. Un report riassume una giornata di posta; le intestazioni di un singolo messaggio ti dicono che cosa ha concluso un ricevente su quel messaggio, adesso. Se puoi mandarti un messaggio di prova, incolla le sue intestazioni nel nostro analizzatore di intestazioni email: legge le dichiarazioni di chi ha ricevuto, non richiede alcun account e non conserva niente.

E quando i report cominceranno ad arrivare, la cosa da tenere d’occhio non è solo che il record continui a essere leggibile, ma che il suo rua continui a nominare te. È il controllo che Sentinely fa in continuo, ed è la differenza fra accorgersene oggi e accorgersene al prossimo audit.