PowerMTA dsnDiag Field Analysis: Complete 2026 Operator Guide

← PowerMTA Operations

PowerMTA dsnDiag Field Analysis: Complete 2026 Operator Guide to Reading Diagnostic Text in Accounting Logs

March 13, 2027·12 min read·Henrik Larsen

Why dsnDiag matters

Every PowerMTA accounting record for a delivery attempt carries the receiving server's response, and the richest part of that response is the dsnDiag field, the diagnostic text the receiving server returned. When an operator needs to understand why a delivery failed, what pattern of failures is occurring, or what a receiving ISP is signalling, dsnDiag is the field that holds the answer in the receiver's own words.

This guide exists because dsnDiag is simultaneously the most informative and the most difficult field in the accounting log. It is the most informative because it carries the specific reason for every outcome, including ISP-specific codes that appear nowhere else. It is the most difficult because it is unstructured text that every receiving MTA phrases differently, full of variable details that complicate analysis. An operator who can read and analyze dsnDiag effectively diagnoses delivery problems precisely; an operator who ignores it because it looks messy works from the coarser structured fields and misses the specifics. The structure of this guide: what dsnDiag contains, its relationship to the structured dsnStatus field, the ISP-specific patterns operators learn to recognize, the technique of grouping dsnDiag for pattern analysis, building classification logic on top of it, the noise problem and how to handle it, the SQL query patterns, and the diagnostic workflow for using dsnDiag to find root causes.

What the dsnDiag field contains

The dsnDiag field contains the diagnostic text the receiving mail server returned for a delivery attempt, the human-readable explanation of what happened.

When PowerMTA attempts a delivery, the receiving server responds with an SMTP response: a response code, often an enhanced status code, and descriptive text. PowerMTA records this in the accounting fields, and dsnDiag captures the descriptive text portion, frequently including the codes embedded in it. A dsnDiag value is essentially the receiving server's own statement of what it did with the message and why.

The content varies by receiver and by outcome:

  • For a delivery (type d record), dsnDiag carries the receiver's acceptance response.
  • For a bounce (type b record), dsnDiag carries the rejection reason.
  • For a transient failure (type t record), dsnDiag carries the deferral reason, frequently a throttling message.

The diagnostic text typically includes the SMTP response code, the enhanced status code, and a descriptive message. For a throttling deferral it might describe the reason for the deferral. For a rejection it might name the policy or condition that caused the rejection. The text is whatever the receiving server chose to say.

dsnDiag is the field that carries the ISP-specific signals. Yahoo's TSS04 throttle code, Microsoft's S-codes, Gmail's specific rate-limit and policy phrases, these appear in the dsnDiag text. They do not appear in the structured enhanced status code, which has no slot for vendor-specific codes. If an operator wants to know that a deferral is specifically a Yahoo TSS04, dsnDiag is where that information lives.

dsnDiag versus dsnStatus

The accounting log has two fields describing a delivery outcome's reason, and understanding the difference is essential.

AspectdsnStatusdsnDiag
ContentEnhanced status code (X.Y.Z)Diagnostic text from the receiver
StructureStructured, machine-parseableUnstructured free text
GranularityBroad categorySpecific reason
ISP-specific codesNo, generic onlyYes, TSS04, S3140, etc.
Best forBroad classificationSpecific cause diagnosis

The dsnStatus field is the enhanced status code: a structured X.Y.Z value. It classifies the outcome into a category, 5.7.1 is a security or policy failure, 5.1.1 is a bad address, 4.2.2 is a full mailbox. This classification is valuable and is the right field for the broad recipient-side versus sender-side distinction that governs suppression decisions.

But the enhanced status code is coarse. Many genuinely different problems share the same enhanced code. Two messages can both have dsnStatus 5.7.1 while one was blocked for a reputation problem and the other for a specific content policy filter; the structured code does not distinguish them. dsnDiag does, because it carries the receiver's specific explanatory text.

The practical approach is to use both fields together. dsnStatus gives the broad category for the high-level classification. dsnDiag gives the specific cause for the actual diagnosis. dsnStatus tells you it was a policy problem; dsnDiag tells you it was specifically a Yahoo TSS04 throttle, which tells you exactly what to do. An analysis that uses only dsnStatus is working at too coarse a grain to identify specific causes; an analysis that uses only dsnDiag loses the clean structured categorization. Together they are complete.

ISP-specific patterns in dsnDiag

The major ISPs each have recognizable patterns in their dsnDiag text, and learning them turns dsnDiag from messy text into actionable signal.

ISPdsnDiag patterns to recognizeWhat they mean
YahooTSS04, TSS09, TS01Throttling, volume or complaint driven
MicrosoftS3140, S3150, S3115, OU-002Spam classification, throttling
GmailRate-limit phrases, 421-4.7.28, unauthenticated mail textThrottling, authentication enforcement
iCloud / Apple451 service messages, load-related textFrequently transient load, not a block

Yahoo patterns. Yahoo's dsnDiag text carries the TSS family of codes. TSS04 is the common throttling code, indicating volume or complaint-driven deferral. TSS09 and TS01 are throttle variants. Recognizing these in dsnDiag tells the operator immediately that Yahoo is throttling and the response is volume reduction. Note that after the 2025 infrastructure consolidation, comcast.net and att.net mail goes through Yahoo and will show Yahoo dsnDiag patterns.

Microsoft patterns. Microsoft's dsnDiag carries S-codes (S3140, S3150, S3115) and OU-codes (OU-002). These indicate spam classification or throttling. Recognizing them maps directly to a Microsoft reputation or content problem.

Gmail patterns. Gmail's dsnDiag is more phrase-based, with descriptive text about rate limits, unsolicited mail, and authentication. Gmail also uses specific sub-codes like 421-4.7.28. Recognizing the Gmail throttle and authentication phrases identifies the Gmail-specific problem.

iCloud patterns. Apple's dsnDiag sometimes carries 451 service-unavailable text during load spikes. The important recognition here is that this is frequently transient load rather than a permanent block, so the response is to retry rather than to treat it as a reputation problem.

An operator who has learned these patterns can read a dsnDiag value and immediately know which ISP is involved and what category of problem it represents. This recognition is the foundation of effective dsnDiag analysis.

Grouping dsnDiag for pattern analysis

Analyzing dsnDiag across many records means finding the recurring patterns, and the technique is grouping on a portion of the text.

The full dsnDiag text varies record to record because receiving MTAs include variable details: the specific recipient, a timestamp, a request ID, a server hostname. Grouping on the full text would treat nearly every record as unique and reveal no patterns.

The solution is to group on a leading portion of the text. The first 60 to 100 characters of dsnDiag typically captures the meaningful part, the code and the descriptive reason, while trimming the variable details that come later. Grouping on this prefix collapses the variation and surfaces the pattern.

SELECT
    substring(dsnDiag, 1, 80) AS diag_prefix,
    count() AS occurrences
FROM pmta_accounting
WHERE type IN ('b', 't')
  AND timeLogged >= now() - INTERVAL 1 DAY
GROUP BY diag_prefix
ORDER BY occurrences DESC
LIMIT 30;

This query groups the bounce and transient records by the first 80 characters of dsnDiag and counts each pattern. The output reveals the common diagnostic patterns: a pattern with a high count is a systematic issue affecting many messages, while patterns with low counts are diffuse, individual problems.

The prefix length is a tuning parameter. Too short, and genuinely different diagnostics collapse together. Too long, and variable details prevent grouping. 60 to 100 characters works for most receivers; the operator adjusts based on what the actual dsnDiag values look like.

The analysis is most useful grouped by receiving domain as well, because the same problem category looks different across ISPs, and the per-ISP view isolates where a problem lives:

SELECT
    rcptDomain,
    substring(dsnDiag, 1, 80) AS diag_prefix,
    count() AS occurrences
FROM pmta_accounting
WHERE type IN ('b', 't')
  AND timeLogged >= now() - INTERVAL 1 DAY
GROUP BY rcptDomain, diag_prefix
ORDER BY occurrences DESC
LIMIT 50;

Building classification from dsnDiag

For ongoing analysis, operators build classification logic that turns the dsnDiag text into structured categories.

The classification matches known patterns in the dsnDiag text and assigns each record a category. The categories are operationally meaningful: throttling, reputation block, authentication failure, address problem, content rejection, transient infrastructure, and so on.

A classification function, in concept:

def classify_dsndiag(diag):
    text = diag.lower()
    # Yahoo throttling
    if 'tss04' in text or 'tss09' in text or 'ts01' in text:
        return 'throttle_yahoo'
    # Microsoft spam/throttle
    if 's3140' in text or 's3150' in text or 'ou-002' in text:
        return 'throttle_microsoft'
    # Gmail rate
    if 'unusual rate' in text or '4.7.28' in text:
        return 'throttle_gmail'
    # Authentication enforcement
    if 'unauthenticated' in text or '5.7.26' in text:
        return 'auth_failure'
    # Address problems
    if 'does not exist' in text or 'no such user' in text:
        return 'bad_address'
    # Mailbox full
    if 'over quota' in text or 'mailbox is full' in text:
        return 'mailbox_full'
    # Reputation/policy
    if '5.7.1' in text or 'blocked' in text:
        return 'reputation_block'
    return 'other'

This classification can be applied during accounting ingestion, adding a category column alongside the raw dsnDiag, so that downstream analysis works on clean categories. Or it can be applied at query time. Either way, it converts the messy text field into countable, trendable, alertable categories.

The classification is built and refined from the grouping analysis. The operator runs the grouping query, sees the common patterns, writes classification rules for them, and over time the classification covers a high fraction of records, leaving only a small unclassified other bucket. The classification should be reviewed periodically because ISPs change their diagnostic text.

The noise and variation problem

dsnDiag is messy, and effective analysis means handling the mess.

Variation across receivers. Every receiving MTA phrases its diagnostics differently. The same conceptual problem, a reputation block, reads completely differently in Yahoo's text, Microsoft's text, and a corporate gateway's text. There is no universal format. Analysis must be receiver-aware, which is why grouping and classification work per receiving domain.

Variable details within a receiver. Even one receiver's diagnostics for the same problem include variable details, the recipient, timestamps, request IDs. This is what the prefix-grouping technique handles.

Text changes over time. ISPs revise their diagnostic text. A classification rule that matched Yahoo's throttle text last year may miss a reworded version. This is why classification needs periodic review.

Embedded delimiters. dsnDiag text can contain commas, which is significant because the accounting log is comma-separated. PowerMTA handles this with proper quoting, and the consumer's CSV parser must respect the quoting. An analysis that splits on commas naively will mangle dsnDiag values containing commas.

Multi-line diagnostics. Some receivers return multi-line SMTP responses, and the dsnDiag may carry the joined text. The analysis should handle this consistently.

Respect the CSV quoting when parsing dsnDiag

The dsnDiag field frequently contains commas, because diagnostic text is natural language. PowerMTA's accounting CSV quotes fields that contain commas so the format stays parseable, but an analysis script that splits accounting lines naively on commas, without a proper CSV parser that respects quoting, will split dsnDiag values in the middle and corrupt every field after them. Always parse the accounting log with a real CSV parser that handles quoted fields. This is a common and silent source of corrupted dsnDiag analysis.

SQL query patterns

The useful query patterns for dsnDiag analysis, assuming accounting data ingested into a SQL store such as ClickHouse:

Top diagnostic patterns overall. What is happening most:

SELECT
    substring(dsnDiag, 1, 80) AS diag,
    count() AS n
FROM pmta_accounting
WHERE type IN ('b', 't')
  AND timeLogged >= now() - INTERVAL 7 DAY
GROUP BY diag
ORDER BY n DESC
LIMIT 25;

Diagnostic patterns for one destination. Isolating one ISP's problems:

SELECT
    substring(dsnDiag, 1, 80) AS diag,
    count() AS n
FROM pmta_accounting
WHERE rcptDomain = 'yahoo.com'
  AND type = 't'
  AND timeLogged >= now() - INTERVAL 1 DAY
GROUP BY diag
ORDER BY n DESC;

Diagnostic trend over time. Is a pattern growing:

SELECT
    toStartOfHour(timeLogged) AS hour,
    count() AS throttle_events
FROM pmta_accounting
WHERE positionCaseInsensitive(dsnDiag, 'tss04') > 0
  AND timeLogged >= now() - INTERVAL 2 DAY
GROUP BY hour
ORDER BY hour;

This trend query counts TSS04 occurrences per hour, showing whether Yahoo throttling is increasing, stable, or resolving.

Diagnostic by source IP. Is a problem IP-specific:

SELECT
    coalesce(dlvProxyServerIp, dlvSourceIp) AS source_ip,
    substring(dsnDiag, 1, 60) AS diag,
    count() AS n
FROM pmta_accounting
WHERE rcptDomain = 'yahoo.com'
  AND type = 't'
  AND timeLogged >= now() - INTERVAL 1 DAY
GROUP BY source_ip, diag
ORDER BY n DESC;

If one source IP shows the throttle diagnostic far more than others, the problem is IP-specific reputation; if spread evenly, it is broader.

Classified category counts. If classification has been applied during ingestion as a category column:

SELECT
    rcptDomain,
    diag_category,
    count() AS n
FROM pmta_accounting
WHERE type IN ('b', 't')
  AND timeLogged >= now() - INTERVAL 1 DAY
GROUP BY rcptDomain, diag_category
ORDER BY n DESC;

The dsnDiag diagnostic workflow

The workflow for using dsnDiag to find the root cause of a delivery problem:

Step 1: scope the problem. Identify which records to analyze, typically the bounce and transient records for a destination or time window where a problem is suspected.

Step 2: group the dsnDiag. Run the prefix-grouping query on the scoped records. This surfaces the dominant diagnostic patterns.

Step 3: identify the dominant pattern. The pattern with the highest count is the systematic issue. Read its dsnDiag text.

Step 4: recognize the ISP signal. Does the dominant pattern carry a recognizable ISP code? TSS04 means Yahoo throttling, S3140 means Microsoft spam classification, a Gmail rate phrase means Gmail throttling. The ISP code maps to a known problem category.

Step 5: cross-reference dsnStatus. Check the dsnStatus on the same records. The enhanced status code confirms the broad category, recipient-side or sender-side, transient or permanent.

Step 6: check the source IP dimension. Group the same diagnostic by source IP. Is the problem on one IP, suggesting IP-specific reputation, or spread across all IPs, suggesting a broader sending-practice problem?

Step 7: check the trend. Run the trend query. Is the pattern growing, stable, or resolving? A growing pattern needs urgent action; a resolving one may just need monitoring.

Step 8: determine and apply the response. The dsnDiag analysis has now identified the specific cause. A Yahoo TSS04 throttle means reduce volume to Yahoo and check complaints. A Microsoft S3140 means address content and reputation. An authentication phrase means fix SPF/DKIM/DMARC. The specific dsnDiag pattern points to the specific response.

Step 9: feed back into classification and patterns. If the dominant pattern was not already in the classification logic, add it. If it suggests an smtp-pattern-list entry (a throttle code that should trigger automatic backoff, a permanent-failure phrase that should bounce), add that. The analysis improves the automated handling for next time.

The dsnStatus that said nothing and the dsnDiag that said everything

An operator we worked with was investigating a deliverability decline at one major ISP. Their analysis worked from the dsnStatus field: they grouped the bounce and transient records by enhanced status code, and the dominant code was 5.7.1, security or policy failure. That told them it was a sender-side problem, which they already suspected, but it did not tell them what the sender-side problem was. They had been stuck at this level of diagnosis for two days, checking authentication, checking blacklists, finding nothing definitive, because 5.7.1 is a broad category that covers many specific causes. We pointed the analysis at dsnDiag instead. The prefix-grouping query on the dsnDiag text immediately showed the dominant pattern: a specific descriptive phrase that named the exact reason the ISP was rejecting the mail, a content-based policy filter triggered by a particular element in the campaign template. The enhanced status code 5.7.1 had been technically correct but useless, because it lumped the specific content-filter rejection in with every other policy and security failure. The dsnDiag text named the actual cause in plain language. With the specific cause identified, the fix took an hour: adjust the campaign template to remove the element triggering the filter. The lesson is the core point about dsnDiag versus dsnStatus: dsnStatus classifies the outcome into a broad category, which is useful but coarse, and an operator who stops at dsnStatus is often left knowing the category but not the cause. dsnDiag carries the receiver's actual words, and the actual words usually name the specific problem. When dsnStatus analysis stalls at a broad category, the next move is always to read the dsnDiag.

The dsnDiag field is the richest diagnostic signal in the PowerMTA accounting log, carrying the receiving server's own explanation of every delivery outcome, including the ISP-specific codes that the structured dsnStatus field cannot hold. It is also the messiest field, unstructured text that varies by receiver and over time. Effective dsnDiag analysis means grouping on a prefix to collapse the variation and surface patterns, building classification logic that turns the text into actionable categories, recognizing the ISP-specific signals, and handling the noise, especially respecting the CSV quoting that protects dsnDiag values containing commas. Used alongside dsnStatus, which gives the broad category, dsnDiag gives the specific cause, and the specific cause is what points to the specific fix. Operators who learn to read and analyze dsnDiag diagnose delivery problems precisely and fast; operators who stop at the coarse structured fields know the category of their problems but spend days searching for the cause that dsnDiag would have named directly.

H
Henrik Larsen

Email Infrastructure Engineer at Cloud Server for Email. Analyzes PowerMTA accounting data to diagnose deliverability problems for ESP clients. Related: PowerMTA Accounting Log Reference, 452 vs 550 Bounce Code Analysis, Pipe Accounting to External Scripts.