What SMTP Actually Is Before We Get Into The Details
SMTP is the protocol that moves email from your outbox to someone else's inbox. It runs on port 25 by default, though most modern setups use port 587 for submission with authentication, or port 465 for implicit TLS. The protocol itself is straightforward: connect, identify yourself, hand off the message, and disconnect. The complicated part is everything that happens between those steps — authentication failures, queue management, relay logic, bounce handling, and the sheer volume of edge cases that crop up when you're dealing with multiple MTAs across different networks. When people talk about SMTP analysis tools, they're usually looking at one of two things: packet-level inspection of SMTP traffic, or application-layer debugging of message flow through an MTA. There's a big difference between the two, and mixing them up gets you nowhere fast. I spent years troubleshooting a situation where a client's mail was silently dropping between two internal Postfix servers. We were looking at the wrong layer the entire first week. The messages weren't failing at the SMTP protocol level at all — they were being rejected by a misconfigured Postfix restriction class after the initial handshake completed successfully. If you're trying to debug something and the SMTP session completes cleanly but the message never arrives, stop looking at the protocol and start looking at the content filters, rate limiting rules, and ACLs on your MTA. For actual packet-level SMTP analysis, Wireshark remains the most practical tool available. It understands SMTP natively, can decode STARTTLS sessions if you provide the server keylog, and handles both active and passive capture scenarios without much fuss. The alternative route is using tcpdump to pull raw captures and then decoding them later, but that adds complexity without much benefit unless you're dealing with unusual encodings or fragmented packets.
I ran into a specific issue last year where an enterprise client was using a custom SMTP relay that injected its own headers and modified the envelope sender under certain conditions. Wireshark showed the outbound messages as clean, but the receiving servers were seeing a completely different set of headers. The problem turned out to be that the relay was performing a mid-session EHLO renegotiation that Wireshark's SMTP dissector wasn't tracking properly across the session boundary. The workaround was relatively simple: I configured Wireshark to follow the TCP stream for the specific SMTP conversations in question rather than relying on the protocol decoder's state machine, which revealed the header injection happening between the DATA command and the final CRLF. That took about twenty minutes once I knew what to look for, but identifying the root cause required understanding how Wireshark's SMTP state tracking works internally.
Setting Up A Working SMTP Analysis Environment
The baseline setup involves capturing traffic on the network segment where your mail flows. If you control the infrastructure, place the capture point at the network edge between your SMTP gateway and the upstream ISP or relay provider. This gives you visibility into both the originating and destination sides of the conversation. If you don't control the network, you're limited to host-level captures on the MTA itself, which means you'll see the outbound session but not what happens after it leaves your network. For local MTA debugging, most people run a test mail server on a spare machine. Postfix and Exim are the two most common choices. Postfix is simpler to configure for basic testing — you can get it running with a minimal main.cf in about ten minutes. Exim gives you more granular control over logging at the cost of configuration complexity. I typically use Postfix for quick smoke tests and switch to Exim when I need detailed delivery chain tracing. Here's a minimal Postfix configuration for local testing:
Get the Full Details

main.cf: myhostname = mail.test.local, mydomain = test.local, myorigin = $mydomain, inet_interfaces = all, mynetworks = 127.0.0.0/8, relay_domains = $mydestination, mailbox_size_limit = 0, recipient_delimiter = +, inet_interfaces = loopback-only for pure local testing. Once the server is running, send a test message using telnet or openssl s_client to port 587. The manual SMTP conversation looks like this: connect to the server, issue EHLO, authenticate if required, issue MAIL FROM, RCPT TO, DATA, enter the message body, terminate with a blank line, then QUIT. Most issues appear during the authentication or relay acceptance phase, not during the actual message transfer.
Reading SMTP Transactions Like A Map
An SMTP transaction has a predictable structure, but the error responses carry most of the useful information. When a server rejects a message, it returns a numeric code followed by a text description. The first digit tells you the category: 2xx means success, 4xx means a temporary failure that the sending MTA should retry, and 5xx means a permanent failure. This distinction matters because many people treat 4xx and 5xx the same way when troubleshooting — they assume the message is dead either way. It isn't. A 4xx response means the receiving server is temporarily unable to accept the message, and your MTA will keep retrying according to its queue schedule. Common causes include rate limiting, greylisting, and resource exhaustion on the receiving end. A 5xx response means the message will never be delivered unless you change something — wrong recipient, domain doesn't exist, policy rejection, or authentication failure. The text after the numeric code is often more informative than the code itself. A response like "550 5.1.1
Common Pitfalls That Waste Hours
Greylisting is the single most frustrating thing you'll encounter when analyzing SMTP traffic. The receiving server intentionally rejects the first attempt with a 4xx code, forcing the sending MTA to retry. Legitimate MTAs retry after a delay — usually somewhere between a few minutes and an hour. Spam generators typically don't retry. The problem is that greylisting makes it look like messages are being lost when they're actually just delayed. If you're seeing a burst of deferred messages that eventually deliver, greylisting is probably responsible. The workaround isn't really a workaround — it's accepting that greylisting exists and adjusting your monitoring expectations accordingly. Sender Policy Framework checks are another common source of confusion. When a receiving server verifies the SPF record for the envelope sender domain and finds a mismatch, it may reject the message with a 550 code. The confusing part is that the message appears to come from a valid address but gets rejected because the sending IP isn't authorized in the domain's SPF record. This commonly happens with mailing lists and relay setups where the original sender's domain and the relay's domain differ. The fix is either updating the SPF record to include the relay IP or configuring the relay to modify the envelope sender to its own domain before forwarding. Queue management on your own MTA deserves attention. Postfix stores deferred messages in the deferred queue directory, and a flooded queue can cause performance degradation across the entire server. I've seen queues grow to millions of messages on misconfigured relay servers, consuming disk space and memory. The solution is to monitor queue depth and set appropriate max_queue_lifetime values. Messages that can't be delivered within the lifetime window are bounced back to the sender. Setting this too high means stale messages clog the queue. Setting it too low means legitimate retries fail prematurely. A typical value is somewhere between 1 and 5 days depending on your use case.

When SMTP Analysis Isn't Enough
There are scenarios where looking at the SMTP protocol itself won't tell you what's happening. Header manipulation, body rewriting, and content filtering all happen at the MTA application layer and don't necessarily leave traces in the SMTP conversation. If a message is being modified between sending and receiving, you need to compare the actual message content at both ends, not just the SMTP transaction logs. Tools like swaks are useful for sending controlled test messages with known headers and body content so you can verify whether modifications are occurring mid-transit. Another limitation: SMTP analysis tells you nothing about deliverability from the recipient's perspective. A message can complete its SMTP transaction successfully and still end up in spam or get blocked by downstream filters. DKIM signing, DMARC alignment, and BIMI records all affect how receiving servers treat your message, but none of that shows up in SMTP protocol analysis. You need separate tools — DKIM verifier, DMARC report analyzers, and sender reputation monitoring — to get the full picture. SMTP is just the transport mechanism. What happens before and after it is where most real problems live. If you're doing this kind of work regularly, I'd recommend keeping a small lab environment with a couple of Postfix instances, a capture workstation, and a test mail client. Having a controlled environment where you can reproduce issues without affecting production saves enormous amounts of time. I've found that setting up a lab takes about an afternoon and pays for itself within a week of troubleshooting.