PowerMTA Messages Stuck in Queue: Complete 2026 Operator Diagnostic Guide

← PowerMTA Operations

PowerMTA Messages Stuck in Queue: Complete 2026 Operator Diagnostic Guide

September 26, 2026·13 min read·Henrik Larsen

Why queue depth investigation matters

Queue depth is the operational metric that signals whether PowerMTA is keeping pace with what applications are sending. Steady-state queue depth tells you delivery throughput matches submission rate; growing queue depth means submission is outpacing delivery; sudden depth spikes signal either submission spikes or delivery problems; persistently deep queues that do not drain indicate stuck queues requiring investigation. Stuck queues are not just an aesthetic issue: messages waiting too long in queue eventually expire (per retry-max-time), bounce as permanent failures, and customers lose deliverability. The faster operators detect and resolve stuck queues, the more messages actually deliver.

This guide exists because queue diagnostics is where the difference between experienced and inexperienced PowerMTA operators shows most clearly. Experienced operators read pmta show queues output and immediately identify the cause; inexperienced operators see deep queues and panic without understanding what specific signal indicates a problem versus normal operation. The structure: distinguishing normal slow processing from actually stuck queues, reading pmta show queues output, detecting backoff mode, monitoring patterns for queue depth, the pmta command set for queue manipulation, accounting log analysis for understanding causes, common patterns operators encounter, Prometheus integration for proactive alerting, and the systematic procedure operators follow during queue incidents.

Normal slow vs actually stuck

The first diagnostic question is whether a deep queue is actually stuck or just processing slowly. The distinction matters because the response is different.

SignalNormal slow processingActually stuck
Queue depth over timeSlowly decreasing or fluctuatingConstant or growing
Active SMTP connectionsSome connections presentZero or very low for extended period
Last Attempt timestampRecent (within retry interval)Stale (beyond expected retry interval)
Recent accounting recordsMix of d/b/t records appearingOnly t records or no records at all
Queue statusNormalFrequently BACKOFF
Operator responseWait and observeInvestigate root cause

The practical test: run pmta show queues twice, 60 seconds apart, and compare the Recip count for suspect queues. If the count decreased, the queue is processing normally (perhaps slower than ideal but not stuck). If the count is the same or higher and no recent successful deliveries appear in accounting, the queue is stuck and needs investigation.

Reading pmta show queues output

The pmta show queues command produces output that experienced operators read at a glance. The columns and their operational meaning:

ColumnMeaningWhat to look for
QueueDestination domain/VMTA poolIdentifies the specific queue
DomainRecipient domainPattern across multiple queues hints at ISP-wide issue
VMTAVirtual MTA namePattern across one VMTA hints at IP-specific issue
StatusNormal, BACKOFF, pausedBACKOFF is the strong signal
RecipRecipients queuedDepth indicator
ConnActive connections nowZero connections plus deep queue is suspicious
RateCurrent delivery rateZero rate plus depth means stuck
Last AttemptWhen PowerMTA last tried deliveryStale timestamp signals problem
First Recipient In QueueOldest waiting message timestampAged messages approaching retry-max-time
Last DiagnosticMost recent SMTP responseIdentifies receiving MTA error pattern

A healthy queue output looks roughly like:

Queue                       Status  Recip  Conn  Rate    LastAttempt  FirstInQ
gmail.com/marketing-pool    Normal  234    5     180/m   00:00:02     00:00:45
outlook.com/marketing-pool  Normal  187    3     120/m   00:00:05     00:01:12

A stuck queue output looks roughly like:

Queue                       Status   Recip  Conn  Rate  LastAttempt  FirstInQ
yahoo.com/marketing-pool    BACKOFF  4823   0     0/m   00:45:23     04:32:18

Reading the stuck queue: 4823 recipients queued, zero active connections, no current delivery rate, last attempt 45 minutes ago (consistent with backoff-retry interval), oldest message has been waiting 4.5 hours. The BACKOFF status is the immediate signal that PowerMTA has decided this destination is throttling and is intentionally waiting between attempts.

Detecting backoff mode

Backoff mode is PowerMTA's protective response when consecutive errors exceed backoff-after threshold. The queue switches from retry-after interval to backoff-retry interval and continues retrying at the longer interval until a successful delivery exits backoff or retry-max-time expires.

Backoff mode detection signals:

  • pmta show queues shows BACKOFF status
  • Last Attempt timestamps align with backoff-retry interval rather than retry-after interval
  • Accounting log shows pattern of t-type records spaced at backoff-retry interval
  • Queue depth grows because retry pace is slower than submission pace

The operator response depends on whether backoff is appropriate or whether the underlying issue has resolved. If the receiving MTA is still returning the error patterns that triggered backoff, leaving backoff mode engaged is correct. If the operator has addressed the underlying issue (reduced send rate, addressed reputation, fixed content) and verified manually that the destination is accepting messages again, manually exiting backoff with pmta set queue --mode=normal accelerates recovery.

# Exit backoff for specific queue
pmta set queue --mode=normal yahoo.com/marketing-pool

# Exit backoff for all queues at once (after broad incident resolution)
pmta set queue --mode=normal */*

The most dangerous mistake: exiting backoff repeatedly without addressing the underlying cause. PowerMTA re-enters backoff after the same threshold of errors recurs, and rapid back-and-forth between normal and backoff modes signals that the operator is fighting the protection mechanism instead of fixing the root cause.

Queue depth monitoring patterns

Production deployments need queue depth monitoring beyond manual pmta show queues invocation. PowerMTA provides several integration points.

Web monitor. PowerMTA's built-in web monitor (typically port 8080 or 1983) displays queue status in browser. Useful for ad-hoc investigation but not for alerting or historical trending.

JSON feed. The web monitor exposes queue data as JSON at /api/queues endpoint. Scripts can parse the JSON to extract queue metrics for downstream tooling.

curl -s http://localhost:8080/api/queues | jq '.queues[] | select(.recip > 1000)'

Accounting log analysis. Queue depth implications can be derived from accounting log timing analysis. Messages in queue produce no records; messages flowing through produce d/b/t records at the rate PowerMTA processes them. Sudden drops in record rate signal queue accumulation.

pmtahttp metrics. Some PowerMTA deployments expose Prometheus-compatible metrics through pmtahttp configurations. Direct scrape into Prometheus enables Grafana dashboards.

The typical production setup combines several: web monitor for ad-hoc investigation, JSON feed scraped by Prometheus exporter, Grafana dashboards showing queue depth trends per VMTA pool and per destination domain, alerting rules on sustained queue depth above threshold.

pmta pause, resume, set queue commands

The PowerMTA command-line provides several queue manipulation operations.

CommandEffectUse case
pmta pause queue domain/vmtaStops delivery to specific queuePause during investigation
pmta pause queue */vmtaPauses all queues using one VMTATake an IP out of rotation
pmta pause queue domain/*Pauses all queues for one destinationStop sending to one ISP
pmta pause queue */*Pauses everythingEmergency stop, rare
pmta resume queue domain/vmtaResumes paused queueAfter investigation completes
pmta set queue --mode=normal domain/vmtaExits backoff mode for queueManual recovery after fix
pmta set queue --mode=normal */*Exits backoff for all queuesAfter incident-wide recovery
pmta delete --queue=domain/*Removes all messages from matching queuesLast resort, stale messages
pmta show queuesDisplays queue status tablePrimary diagnostic command
pmta show statusOverall PowerMTA statusService health check
pmta reset countersResets statistics countersAfter incident, fresh metrics

The substantive operational patterns: pause queues during investigation rather than letting them continue running while operator analyzes; use pmta set queue normal sparingly because exiting backoff repeatedly without addressing root cause produces oscillation; reserve pmta delete for situations where stale messages exceed retry-max-time anyway and the message value has dropped below the cost of further retry attempts.

Accounting log analysis for causes

Stuck queues always leave evidence in PowerMTA accounting log. The diagnostic queries:

What is happening at the destination level?

SELECT 
    dsnStatus,
    substring(dsnDiag, 1, 100) AS diag_preview,
    count() AS occurrences
FROM pmta_accounting
WHERE type = 't'
  AND queue = 'yahoo.com'
  AND timeLogged >= now() - INTERVAL 1 HOUR
GROUP BY dsnStatus, diag_preview
ORDER BY occurrences DESC
LIMIT 10;

The query identifies the dsnDiag patterns causing transient failures. Yahoo TSS04 indicates throttling due to complaints; Yahoo 421 indicates connection refused or temporary unavailable; Microsoft S3140 indicates spam classification.

What is the timing pattern of attempts?

SELECT 
    toStartOfMinute(timeLogged) AS minute,
    count() AS attempts
FROM pmta_accounting
WHERE queue = 'yahoo.com'
  AND timeLogged >= now() - INTERVAL 2 HOURS
GROUP BY minute
ORDER BY minute;

The query shows whether PowerMTA is actually attempting deliveries. Sparse attempts at backoff-retry intervals indicate backoff mode; no attempts at all indicates a deeper problem.

Which outbound IP is affected?

SELECT 
    coalesce(dlvProxyServerIp, dlvSourceIp) AS source_ip,
    count() AS attempts
FROM pmta_accounting
WHERE queue = 'yahoo.com'
  AND timeLogged >= now() - INTERVAL 2 HOURS
GROUP BY source_ip
ORDER BY attempts DESC;

If one IP shows substantially more attempts than others, the issue is likely IP-specific reputation. If attempts spread across all IPs in the VMTA pool, the issue is reputation-wide or destination-wide.

Common stuck queue patterns

Operators encounter recognizable patterns repeatedly. The common patterns and their resolutions:

Pattern 1: Yahoo TSS04 throttling cascade. Yahoo returns TSS04 when complaint rate from sender IPs crosses Yahoo's threshold. PowerMTA enters backoff for yahoo.com queue. Queue depth grows. Continued retries continue receiving TSS04 because the underlying complaint situation has not resolved. Resolution: investigate complaint source, reduce send rate to Yahoo destinations, address content or list quality issues, wait 48-72 hours for reputation to begin recovering, optionally pause Yahoo queue temporarily during reputation recovery.

Pattern 2: Microsoft S3140 spam classification. Microsoft returns S3140 when EOP classifies sender as spam-likely. Pattern similar to Yahoo TSS04 but Microsoft-specific. Resolution: same general approach plus investigate authentication alignment (Microsoft is strict on SPF/DKIM/DMARC), reduce content elements that frequently trigger filters (excessive images, suspicious links, ALL CAPS), evaluate Microsoft SNDS-JMRP data for specific reputation signals.

Pattern 3: DNS resolution failure. PowerMTA cannot resolve MX records for a destination. Queue grows because messages cannot be attempted. Less common but happens when destination DNS has issues or when PowerMTA host DNS resolver has issues. Resolution: verify DNS resolution from PowerMTA host with dig MX problemdomain.com; if PowerMTA host cannot resolve but other hosts can, fix DNS configuration on PowerMTA host; if no host can resolve, the destination has DNS issues and queue will resolve when their DNS recovers.

Pattern 4: Outbound network connectivity loss. Cloud provider or firewall blocks outbound port 25 to specific destinations. Connections time out. Queue grows because no successful deliveries occur. Resolution: test outbound TCP from PowerMTA host with telnet receiver-mx 25; if blocked, contact cloud provider or firewall administrator to lift restriction; AWS EC2 commonly blocks outbound 25 for new accounts.

Pattern 5: Outbound IP on RBL. Outbound IP gets listed on Spamhaus or other reputation list. Many receiving MTAs reject from listed IPs. Queue grows across multiple destinations simultaneously. Resolution: verify IP listing status at mxtoolbox.com/blacklists.aspx; follow delisting process at the specific RBL (Spamhaus has form for delisting); pause queues for IP during delisting process; consider IP rotation while delisting pending.

Pattern 6: Authentication misconfiguration. Receiving MTAs reject due to SPF failure, DKIM signature invalid, or DMARC alignment failure. Queue grows for specific destinations (some MTAs more strict than others). Resolution: verify SPF includes outbound IPs, verify DKIM signing produces valid signatures (test with mail-tester.com), verify DMARC alignment for the From domain.

Pattern 7: Disk full preventing accounting writes. Disk fills up, PowerMTA cannot write accounting records, may pause queue processing. Queue grows because no deliveries occur. Resolution: monitor disk usage proactively, configure log rotation to prevent accumulation, increase disk capacity if needed.

Pattern 8: Configuration reload that broke something. Operator made config change, reloaded PowerMTA, some queues now misbehaving. Resolution: review recent config changes, verify syntax with pmta config check equivalent, roll back recent changes to confirm cause.

The "everything broke after reload" pattern

One of the most common stuck-queue scenarios: operator makes a configuration change, reloads PowerMTA, queues stop processing or process incorrectly. The typical cause: syntax error in the new config that PowerMTA accepted but interpreted unexpectedly (PowerMTA's config parser is sometimes permissive in ways that surprise operators). Always test config changes in staging before reloading production. Keep a known-good config backup before any change. If queues misbehave after reload, the first investigation step is reviewing the diff of recent config changes, not assuming the issue is reputation or network.

Prometheus/Grafana alerting integration

Production PowerMTA deployments benefit from Prometheus/Grafana integration that surfaces queue depth signals before they become visible failures.

The architecture: a PowerMTA exporter scrapes /api/queues JSON endpoint, exposes Prometheus metrics, Prometheus scrapes the exporter, Grafana dashboards display queue trends, AlertManager fires alerts on threshold breaches.

Example exporter pattern (sketch):

#!/usr/bin/env python3
# Simplified PowerMTA Prometheus exporter
import json
import requests
from prometheus_client import start_http_server, Gauge

queue_depth = Gauge('pmta_queue_depth', 'Messages in queue', ['domain', 'vmta', 'status'])
queue_conn = Gauge('pmta_queue_connections', 'Active connections', ['domain', 'vmta'])
queue_rate = Gauge('pmta_queue_rate', 'Delivery rate per minute', ['domain', 'vmta'])

def collect():
    response = requests.get('http://localhost:8080/api/queues').json()
    for q in response.get('queues', []):
        labels = (q['domain'], q['vmta'], q['status'])
        queue_depth.labels(*labels).set(q['recip'])
        queue_conn.labels(q['domain'], q['vmta']).set(q['conn'])
        queue_rate.labels(q['domain'], q['vmta']).set(q['rate'])

if __name__ == '__main__':
    start_http_server(9100)
    while True:
        collect()
        time.sleep(30)

Prometheus alerting rules that capture common stuck-queue patterns:

# Alert when queue depth exceeds threshold for sustained period
- alert: PMTAQueueDepthHigh
  expr: pmta_queue_depth > 5000
  for: 15m
  annotations:
    summary: "PowerMTA queue {{ $labels.domain }}/{{ $labels.vmta }} depth {{ $value }} for 15m+"

# Alert on backoff mode persisting
- alert: PMTABackoffPersistent
  expr: pmta_queue_depth{status="BACKOFF"} > 100
  for: 30m
  annotations:
    summary: "PowerMTA queue {{ $labels.domain }} in backoff with {{ $value }} messages for 30m+"

# Alert on zero connections but deep queue
- alert: PMTAQueueStalled
  expr: pmta_queue_depth > 1000 and pmta_queue_connections == 0
  for: 10m
  annotations:
    summary: "PowerMTA queue {{ $labels.domain }} has {{ $value }} messages but zero connections for 10m+"

These rules detect stuck queues within minutes rather than waiting for operators to discover them through manual checks or downstream customer complaints.

Systematic diagnostic procedure

The procedure operators follow during stuck queue incidents:

Step 1: confirm queue is actually stuck. Run pmta show queues twice, 60 seconds apart. Compare Recip counts. Decreasing means processing (not stuck), constant or growing means stuck.

Step 2: identify the affected queues. Pattern recognition from pmta show queues output. Single queue means destination-specific issue; multiple queues for same destination across VMTAs means destination-wide; multiple destinations for one VMTA means VMTA-specific (typically IP reputation); all queues affected means PowerMTA-wide issue (DNS, disk, network).

Step 3: check queue status. Is the queue in BACKOFF? If yes, accounting log will show backoff-paced retry attempts. If no, deeper investigation needed.

Step 4: query accounting for actual response. Recent t-type records for the affected queue. What does dsnDiag say? The receiving MTA response identifies the cause.

Step 5: check outbound networking. telnet to receiver MX on port 25 from PowerMTA host. If connection refused or timeout, network issue. If connection succeeds, network is fine.

Step 6: check IP reputation. Query mxtoolbox for outbound IPs. If listed on RBL, that explains the rejection. If not listed, reputation degradation is more subtle (per-receiver reputation scoring).

Step 7: check authentication. SPF, DKIM, DMARC alignment for the affected sending domain. Verify with mail-tester.com that authentication is correct.

Step 8: check DNS resolution. dig MX for affected destination from PowerMTA host. If DNS fails, that explains why deliveries are not attempted.

Step 9: check PowerMTA log. /var/log/pmta/log for any error messages related to the affected destination or VMTA.

Step 10: take corrective action. Based on identified cause: address reputation issue if reputation, fix DNS if DNS, contact provider if network, fix authentication if auth, exit backoff if underlying issue resolved.

Step 11: monitor recovery. Watch queue depth over next 1-2 hours. Decreasing means corrective action working; constant or growing means action insufficient or wrong cause identified.

Step 12: document. Record what was stuck, what cause was identified, what action resolved it, what monitoring would have detected earlier. Build operational knowledge for future incidents.

The "DNS resolver upgrade incident"

An operator we worked with reported multiple PowerMTA queues growing simultaneously across diverse destinations. The pattern (multiple destinations affected) ruled out single-domain reputation. Step 5 (network check) and Step 6 (IP reputation) both came back clean. Step 8 revealed the cause: dig from the PowerMTA host returned SERVFAIL for many domains. A recent unattended-upgrades cycle had updated systemd-resolved configuration in a way that broke DNS for external queries. Reverting the resolver configuration restored DNS within minutes; queues that had accumulated 12K-30K messages each drained over the next hour without any reputation damage because the messages had been waiting for DNS, not getting rejected by receivers. The lesson: when stuck queue pattern affects multiple unrelated destinations, the cause is typically infrastructure-level (DNS, network, disk, PowerMTA service health) rather than destination-specific. Following the diagnostic procedure systematically identifies these root causes faster than guessing at deliverability theories.

Stuck PowerMTA queues are an inherent reality of high-volume email infrastructure. The receiving environment varies, ISPs throttle, networks have issues, reputation events occur. What distinguishes resilient operations from fragile ones is the diagnostic discipline applied when queues stick. The pmta show queues command, accounting log analysis, network and DNS verification, IP reputation checking, and authentication validation together identify root causes for almost every stuck-queue scenario. Combined with proactive Prometheus alerting that surfaces signals early, operators can resolve incidents in minutes that would otherwise extend into hours. The investment in mastering queue diagnostics pays back substantially because queue incidents recur and each saved hour of diagnostic confusion is an hour of customer-facing deliverability protected.

H
Henrik Larsen

Email Infrastructure Engineer at Cloud Server for Email. Diagnoses PowerMTA queue incidents for ESP clients across diverse infrastructure configurations. Related: retry-after Directive and Backoff, Delivery Rate Suddenly Dropped, Queue Depth Monitoring.