• Indonesian
  • English
  • Exim Log cPanel Deep Dive: Reading Logs & Troubleshooting

    Kecepatan:
    ⏱ 17 min read
    Difficulty: Intermediate
    Last Updated: July 2026
    Tested On: cPanel/WHM 118.x, AlmaLinux 8/9, CloudLinux 8/9, Exim 4.96+

    I remember the first time a client called me panicking because their business emails were bouncing back with no clear explanation. I pulled up the Exim mainlog on their cPanel server and stared at lines that told me almost nothing useful. The default logging was so sparse that I spent over two hours just trying to figure out where in the delivery chain things were falling apart. That was the day I learned that Exim’s default logging is built for performance, not for troubleshooting.

    Think of Exim logs like the black box recorder on an airplane. When everything goes smoothly, you never think about it. But when something goes wrong — a plane crashes, or in our case, emails bounce or disappear — you need every bit of data that recorder captured. Default Exim logging gives you the flight number and destination, but not the engine readings, weather conditions, or pilot inputs. Verbose logging changes that equation entirely.

    In this guide, we are going to walk through everything a NOC engineer needs to know about Exim logs in cPanel. From enabling verbose logging to reading log notation, mastering CLI commands, decoding SMTP error codes like 421, 450, 550, and 554, and understanding how SpamAssassin and SpamBox integrate with the mail flow. Everything here comes from real production experience handling hundreds of servers daily.

    Why Default Exim Logging Falls Short

    Before we dive into commands and configs, you need to understand why default Exim logging is insufficient for serious troubleshooting. By default, Exim only records minimal information — enough to see that an email arrived and was delivered, but not enough to understand why a specific message failed, why routing went wrong, or why SMTP authentication suddenly stopped working.

    The real-world impact is significant. When a client reports a bounced email, you end up guessing instead of reading what actually happened in the log. A troubleshooting session that should take ten minutes stretches into an hour or more. In business contexts, a failed email delivery can mean a lost deal, an unpaid invoice, or critical communication that never reaches its destination.

    The good news is that Exim gives you full control over what gets logged. You just need to know where to configure it and what parameters to use. The bad news is that most cPanel server administrators never touch the logging configuration, which means they are working with a significant blind spot every time they try to diagnose email issues.

    Enabling Verbose Logging in WHM

    There are two primary ways to enable verbose logging in Exim on cPanel: through the WHM interface and by directly editing the configuration file.

    Method 1: WHM Advanced Editor

    Login to WHM, navigate to Service Configuration, then Exim Configuration Manager, and click the Advanced Editor tab. Look for the log_selector section where you can add the parameters you need. Here are the most useful ones:

    Parameter Function When to Use
    +all Enable all verbose logging Intensive debugging (not for long-term production)
    +address_rewrite Log every address rewrite process Forwarding and filtering issues
    +dns_lookup Log every DNS lookup DNS and MX record problems
    +host_lookup_failed Log failed DNS lookups DNS timeouts and resolution failures
    +reject Log all email rejections Spam filtering and blocked senders
    +smtp_confirmation Show SMTP confirmation from remote server Debugging bounces and remote rejections
    +smtp_protocol_error Log SMTP protocol errors Failed SMTP communication
    +tls_cipher Show TLS cipher information Encryption and TLS handshake debugging

    My recommendation for production servers: do not use +all because the logs will become enormous and consume significant disk I/O. Instead, use a targeted combination of parameters. Here is a solid configuration for debugging email delivery issues:

    log_selector = +address_rewrite +dns_lookup +host_lookup_failed +reject +smtp_confirmation +smtp_protocol_error

    If you genuinely need full debugging (like during a critical incident investigation), use +all but remember to revert to a lighter configuration once you are done. Leaving +all active on a busy server for days will generate gigabytes of log data.

    Method 2: Direct Configuration File Edit

    Open /etc/exim.conf and find the log_selector line. If it does not exist, add it in the Main configuration section:

    log_selector = +address_rewrite +dns_lookup +host_lookup_failed +reject +smtp_confirmation

    After editing, restart Exim:

    systemctl restart exim

    Or through WHM: Home, Restart Services, Exim Mail Server.

    WHM Exim Configuration Manager Advanced Editor showing log_selector configuration panel

    Essential Exim CLI Commands Every NOC Engineer Must Know

    Once verbose logging is active, you need to master the Exim CLI commands that let you read and analyze logs. These are the commands I use almost every single day:

    Basic Monitoring Commands

    Command Function Use Case
    exiwhat Show what Exim is currently doing Check for stuck processes
    exim -bpc Count emails in queue Check for queue overflow
    exim -bp List emails in queue See which emails are pending
    exim -bp | head -30 Show top 30 queued emails Quick queue check
    exigrep <pattern> /var/log/exim/mainlog Search for specific pattern in log Trace a specific email
    exim -Mvh <message-id> Show email headers Inspect a specific email
    exim -Mvb <message-id> Show email body Check email content
    exim -Mra <message-id> Resend email from queue Retry delivery
    exim -Mrm <message-id> Remove email from queue Delete spam/stuck mail (CAUTION!)
    Security Warning: Backup Before Removing Emails from Queue

    Before running exim -Mrm, make sure you have:

    1. Backed up the queue list: exim -bp > /tmp/mailqueue-backup-$(date +%Y%m%d-%H%M).txt
    2. Verified the target with exim -Mvh <message-id>
    3. Confirmed the email is genuinely spam or stuck, not a valid client message

    Running deletion without verification can cause permanent data loss — important client emails may disappear forever.

    Log Search and Analysis Commands

    # Find all emails from a specific IP
    exigrep "192.0.2.10" /var/log/exim/mainlog
    
    # Find all emails to a specific address
    exigrep "user@client-a.com" /var/log/exim/mainlog
    
    # Find all errors from the last 24 hours
    exigrep "== " /var/log/exim/mainlog | grep "$(date +%Y-%m-%d)"
    
    # Find all bounces
    exigrep "** " /var/log/exim/mainlog | tail -20
    
    # Find all rejected emails
    exigrep "rejected" /var/log/exim/mainlog | tail -20
    
    # Find all successfully delivered emails
    exigrep "=> " /var/log/exim/mainlog | tail -30

    Understanding Exim Log Notation Symbols

    This is the most critical part to understand. Exim uses symbolic notation to mark activity types in its logs. If you do not understand these symbols, reading Exim logs will be like trying to navigate a foreign city without a map.

    Symbol Meaning
    <= Email received (arrived at server)
    => Email delivered successfully
    -> Email forwarded or copied
    ** Email bounced (failed, returned to sender)
    == Email deferred (delivery temporarily delayed)

    The reading pattern is left-to-right. <= means the email arrived, then => means it was delivered, ** means it bounced, and == means it was deferred. From these symbol combinations, you can map the entire journey of an email from arrival to completion.

    Complete Log Example and Analysis

    Let us look at a real log example and learn to read it step by step:

    2026-07-20 09:15:33 [45231] <= orders@shop-client.com H=mail.shop-client.com [203.0.113.25] P=ESMTPS X=TLSv1.3 TLS_AES_256_GCM_SHA384 CV=no C="250 OK id=1mN8k2-0003ABC-123" S=4521 I=5 E=none N=8 QT=0.002 DT=0.001
    2026-07-20 09:15:34 [45231] => admin@mydomain.com R=virtual_user T=virtual_delivery H=local [127.0.0.1] C="250 OK" QT=0.8 DT=0.799
    2026-07-20 09:15:34 [45231] => sales@mydomain.com R=virtual_user T=virtual_delivery H=local [127.0.0.1] C="250 OK" QT=0.8 DT=0.799
    2026-07-20 09:16:45 [45232] <= newsletter@marketing-tool.com H=relay.marketing-tool.com [198.51.100.50] P=ESMTPS X=TLSv1.2 TLS_AES_128_GCM_SHA256 CV=no C="250 OK id=2kL9m3-0004DEF-567" S=15234 I=8 E=none N=12 QT=0.003 DT=0.002
    2026-07-20 09:16:46 [45232] == user@mydomain.com R=lookuphost T=remote_smtp H=mx1.mydomain.com [203.0.113.10] C="421 4.7.1 Try again later" QT=1.2 DT=1.198
    2026-07-20 09:16:46 [45232] == user@mydomain.com R=lookuphost T=remote_smtp H=mx2.mydomain.com [203.0.113.11] C="421 4.7.1 Try again later" QT=1.2 DT=1.198
    2026-07-20 09:21:46 [45232] == user@mydomain.com R=lookuphost T=remote_smtp H=mx1.mydomain.com [203.0.113.10] C="421 4.7.1 Try again later" QT=5.0 DT=4.999
    2026-07-20 09:31:47 [45232] == user@mydomain.com R=lookuphost T=remote_smtp H=mx1.mydomain.com [203.0.113.10] C="450 4.7.25 IP not in whitelist" QT=10.0 DT=9.998
    2026-07-20 09:31:47 [45232] ** user@mydomain.com: H=mx1.mydomain.com [203.0.113.10] C="450 4.7.25 IP not in whitelist — too many connections" QT=10.0 DT=9.998
    2026-07-20 09:31:47 [45232] Frozen (delivery error message)
    2026-07-20 09:31:47 [45232] <= <> R=double-bounce T=double_bounce S=0 QT=0.001 DT=0.001

    Here is the trace from start to finish:

    • Line 1 (<=): Email arrives from orders@shop-client.com via TLS. Message ID is 45231. Everything normal here.
    • Lines 2-3 (=>): Email successfully delivered to admin@mydomain.com and sales@mydomain.com locally. Two recipients handled.
    • Line 4 (<=): New email arrives from newsletter@marketing-tool.com. Message ID 45232.
    • Lines 5-6 (==): Delivery to user@mydomain.com fails on both MX1 and MX2 — remote server responds 421 4.7.1 Try again later. The remote server is busy or rate limiting.
    • Line 7 (==): First retry after 5 minutes — still fails with same code.
    • Line 8 (==): Second retry — error changes to 450 4.7.25 IP not in whitelist. Our server IP hit a rate limit or temporary block.
    • Line 9 (**): BOUNCE — email fails permanently after retries exhausted. Full error message displayed.
    • Line 10 (Frozen): Email frozen in queue due to delivery error.
    • Line 11 (<=): Double bounce recorded — the bounce message itself also failed to deliver.

    From this trace, we can conclude: the problem is not on our local server but on the remote MX server rejecting connections because our IP hit rate limiting. Solution: check whether our IP is listed in any RBLs and consider adjusting retry configuration.

    Decoding Exim SMTP Error Codes

    Now we get to the section you have been waiting for — understanding Exim error codes. Exim follows standard SMTP reply codes but adds internal details that are extremely helpful for troubleshooting.

    Code 421 — Service Temporarily Unavailable

    Error 421 means the destination server is not ready to receive email. This is temporary — Exim will automatically retry. But if it keeps appearing, there is a problem that needs attention.

    2026-07-20 10:05:12 [67890] == recipient@external.com R=lookuphost T=remote_smtp H=mx.external.com [203.0.113.50] C="421 4.7.1 Service temporarily overloaded" QT=0.5 DT=0.499
    2026-07-20 10:10:13 [67890] == recipient@external.com R=lookuphost T=remote_smtp H=mx.external.com [203.0.113.50] C="421 4.3.2 Not currently accepting mail" QT=5.0 DT=4.998
    2026-07-20 10:25:15 [67890] == recipient@external.com R=lookuphost T=remote_smtp H=mx.external.com [203.0.113.50] C="421 4.7.1 Service temporarily overloaded" QT=15.0 DT=14.997
    2026-07-20 11:05:16 [67890] => recipient@external.com R=lookuphost T=remote_smtp H=mx.external.com [203.0.113.50] C="250 OK id=3mP7q1-0008GHI-901" QT=40.0 DT=39.995

    In this example, the email is initially rejected due to server overload. Exim retries several times and finally succeeds on the fourth attempt after 40 minutes. If you see this pattern, do not panic — Exim is working as designed.

    Code 450 — Access Denied (Temporary)

    450 means there is a temporary access issue. The most common causes: rate limiting, IP temporarily blacklisted, or authentication not yet completed.

    2026-07-20 14:22:10 [11223] == client@partner.com R=lookuphost T=remote_smtp H=mx.partner.com [198.51.100.15] C="450 4.7.1 IP not in whitelist" QT=0.3 DT=0.298

    From this log, our server IP is likely on a temporary whitelist at the partner server. Check our IP against common RBLs:

    # Check server IP against various RBLs
    dig +short 10.0.0.1.zen.spamhaus.org
    dig +short 10.0.0.1.b.barracudacentral.org
    dig +short 10.0.0.1.bl.spamcop.net

    Code 451 — Local Processing Error (Temporary)

    451 indicates a local error at the destination server. Also temporary with automatic retry. Usually related to DNS issues or server restarts in progress.

    Code 452 — Insufficient Storage (Temporary)

    452 means the mailbox is full or the server ran out of storage. Frequently appears for shared hosting mailboxes that have exceeded their quota.

    2026-07-20 16:44:55 [33445] ** user@hosting-client.com: Remote host said: 452 4.2.2 Mailbox quota exceeded QT=0.001 DT=0.001

    Solution: login to the client cPanel, check disk usage under Email Accounts, and ask the client to clean up their mailbox or upgrade their quota.

    Code 550 — Mailbox Not Found / Relay Denied (Permanent)

    This is a permanent error — Exim will not retry because the destination server rejected definitively. 550 has several important sub-variants:

    # 550 User not found
    2026-07-20 17:05:12 [55667] ** nonexistent@client-a.com R=lookuphost T=remote_smtp H=mx.client-a.com [203.0.113.20] C="550 5.1.1 The email account that you tried to reach does not exist" S=189 QT=0.5 DT=0.499
    
    # 550 Relay denied
    2026-07-20 17:10:33 [66778] ** spammer@random-domain.com R=lookuphost T=remote_smtp H=mx.random-domain.com [198.51.100.30] C="550 5.7.1 Relaying denied" S=201 QT=0.3 DT=0.298
    
    # 550 Blocked — sender blacklisted
    2026-07-20 17:15:44 [77889] ** sender@blacklisted-domain.com R=lookuphost T=remote_smtp H=mx.external.com [203.0.113.40] C="550 5.7.1 Message rejected — see https://www.spamhaus.org/query/bl/" S=312 QT=0.4 DT=0.398

    Code 553 — Mailbox Name Not Allowed

    553 usually appears when the email address is syntactically invalid or the destination server does not recognize the domain.

    Code 554 — Transaction Failed

    554 is the catch-all for permanent errors that do not fit other categories. Frequently appears when the destination server rejects email due to poor IP reputation or content filtering rules.

    Code Type Exim Action Common Cause Solution
    421 Temporary Auto-retry Server overload, maintenance Wait, check remote server status
    450 Temporary Auto-retry Rate limit, temporary IP block Check RBLs, wait for cooldown
    451 Temporary Auto-retry DNS error, server restart Verify DNS MX records
    452 Temporary Auto-retry Mailbox full, quota exceeded Clean mailbox or upgrade quota
    550 Permanent Bounce User, relay denied, blacklisted Verify address, check IP reputation
    553 Permanent Bounce Invalid email syntax, wrong domain Check recipient email address
    554 Permanent Bounce Transaction failed, content filter Check email content, IP reputation

    SpamAssassin and SpamBox Integration

    SpamAssassin and SpamBox are two components that significantly impact email behavior on cPanel servers. If you do not understand how both integrate with Exim, you will struggle when client emails end up in spam folders unexpectedly.

    SpamAssassin

    SpamAssassin works by adding an X-Spam-Score header to every incoming email. On cPanel, the default threshold for marking email as spam is typically 5.0. You can check the spam score in Exim logs:

    # Find all emails marked as spam
    exigrep "X-Spam-Score" /var/log/exim/mainlog | tail -20
    
    # Find emails with a specific spam score
    exigrep "X-Spam-Score: [89]" /var/log/exim/mainlog

    For detailed SpamAssassin scoring, look at the X-Spam-Status header:

    X-Spam-Status: No, score=8.2 required=5.0 tests=RCVD_IN_BL_SPAMHAUS,HTML_IMAGE_RATIO_02,MISSING_HTML_TAG,URIBL_BLACK autolearn=unavailable version=3.4.6

    From this log, you can see the email scored 8.2 (above the 5.0 threshold), so it was marked as spam. The primary cause is the Spamhaus blacklist test (RCVD_IN_BL_SPAMHAUS) along with several other tests.

    SpamBox

    SpamBox stores flagged spam in a .Spam folder in the user mailbox instead of blocking it outright. This is good because users can still check their spam folder. But sometimes legitimate emails end up there too, and users do not realize it.

    The SpamBox path in cPanel:

    /home/username/mail/domain.com/user/.Spam/

    Make sure the permissions on this directory are correct. I once handled a case where the .Spam folder had wrong permissions (644 instead of 711), causing SpamBox to fail writing emails to the folder. The result: all spam emails bounced back to senders instead of being filed.

    # Check mailbox directory permissions
    ls -la /home/username/mail/domain.com/user/
    
    # Correct permissions for mailbox directories
    drwx--x---  3 username  username  4096 Jul 20 09:00 .
    drwx--x---  5 username  username  4096 Jul 20 09:00 ..
    drwx------  2 username  username  4096 Jul 20 09:00 cur
    drwx------  2 username  username  4096 Jul 20 09:00 new
    drwx------  2 username  username  4096 Jul 20 09:00 tmp
    drwx------  2 username  username  4096 Jul 20 09:00 .Spam

    Note that mailbox directories use drwx--x--- (711 for directories, 700 for subfolders). This is a critical security setting that prevents other users on the same server from reading mailbox contents.

    Problem Log Symptom Root Cause Solution
    Legitimate email marked as spam X-Spam-Score above threshold SpamAssassin false positive Add whitelist in SpamAssassin config
    SpamBox folder not writable Delivery failed to local Wrong folder permissions (not 711) Fix: chmod 711 .Spam
    Email bounced without clear reason ** in log without details Missing or wrong DNS PTR record Setup PTR record for server IP
    SMTP authentication failing 535 authentication failed Plain text auth disabled / wrong password Check “Require SSL” in email client

    Common Problem Patterns in Exim Logs

    Based on experience handling hundreds of servers, here are the most frequent problem patterns:

    1. Incorrect DNS Configuration (MX/PTR)

    One of the most common reasons for email bounces. If MX records are wrong or the PTR record for your server IP is not configured, emails from your server will be rejected by almost all major mail servers.

    # Check your domain MX record
    dig +short MX yourdomain.com
    
    # Check PTR record for your server IP
    dig +short -x 203.0.113.10
    
    # Verify forward-confirmed reverse DNS
    hostname -f

    The PTR record must resolve to your server hostname, and your hostname must resolve back to the same IP (forward-confirmed reverse DNS). If they do not match, many mail servers will reject emails from your IP.

    2. SMTP Authentication Failure

    Sometimes clients complain they cannot send email from their email client (Outlook, Thunderbird). In the Exim log you will see:

    2026-07-20 20:15:33 [88990] authenticator failed for (client-pc-123): 535 Incorrect authentication data

    Causes vary: wrong password, plain text authentication disabled in WHM while the client is not using SSL, or issues with the cPanel dovecotauth driver. Check in WHM under Exim Configuration Manager, Security tab, and ensure SMTP Authentication is properly enabled.

    3. Queue Overflow

    When thousands of emails get stuck in queue, server performance drops dramatically. Check queue count:

    exim -bpc

    If the number is in the hundreds or thousands, there is a serious problem. See what is stuck:

    exim -bp | head -50

    For more details on queue management, read our guide on Exim Mail Queue Management.

    Pro Tips and Warnings

    1. Never leave +all enabled on production for extended periods. Logs can reach gigabytes per day and burden disk I/O. Enable only during troubleshooting, then revert.
    2. Always check DNS first before concluding there is a problem with the local system. 60% of email issues actually originate from DNS misconfiguration.
    3. Use exigrep wisely. Overly generic patterns will return thousands of irrelevant results. Always include a specific message ID or IP address.
    4. Backups are mandatory before destructive operations. This is not optional — it is required. One mistake can mean a client’s important email is lost forever.
    5. Pay attention to timestamps. When investigating an email bounce, start from the time of the incident and trace forward. Do not start from the last lines of the log.
    6. Check RBLs regularly. Your server IP can end up on a blacklist at any time. Set up monitoring for hourly auto-checks. Our guide on Checking IP Blacklist RBL covers this in detail.
    7. Mailbox directory structure must be correct. The folder /home/username/mail/domain/user/ must have proper structure with 711 permissions for directories and 700 for subfolders. See also our Email Troubleshooting cPanel guide for more details.
    8. Understand Exim retry rules. Exim does not immediately remove failed emails. There is a retry mechanism that determines when an email will be attempted again. Check retry configuration in Exim Retry Configuration Guide.

    Quick Troubleshooting Decision Tree

    When you receive an email issue report, follow this flow:

    1. Check queue first: exim -bpc — if high, there is a delivery problem
    2. Check log for specific message ID: exigrep "<message-id>" /var/log/exim/mainlog
    3. Read the symbols: <= arrived, => delivered, == deferred, ** bounced
    4. Check error code: 4xx is temporary (retry), 5xx is permanent (bounce)
    5. Trace from start to finish: Begin at the first line, follow the flow

    Conclusion

    Reading Exim logs demands attention to detail — you need to understand every symbol, every error code, and be able to trace an email journey from start to finish. But once you master the patterns, troubleshooting email becomes significantly faster and more accurate. Remember: always verify DNS records and server RBL status before concluding the problem is with your local system. And most importantly — backup first, then execute.

    Have questions about Exim logs? Our NOC team handles this daily — reach out to us if you need direct assistance with email issues on your server.

    Q: Why can I not see verbose logs in Exim even after changing log_selector in WHM?

    There are several possible causes. First, make sure you restarted Exim after changing the configuration — editing the config file alone is not enough, Exim must be reloaded to apply changes. Second, verify your syntax is correct — a single typo in the log_selector parameter can prevent the entire configuration from taking effect. Third, check if there is an override file at /etc/exim.conf that might be overriding your WHM settings. You can verify by running exim -bV to see the actually active configuration.

    Q: My email is stuck in queue with status “Frozen” — what does that mean and how do I fix it?

    Frozen means Exim has stopped attempting to deliver that email because it exceeded the retry limit or encountered a permanent delivery error. To address this, first check why it is frozen with exim -Mvh <message-id> to view the header, then exim -Mvb <message-id> for the body. If you believe the email is valid, try resending with exim -Mra <message-id>. If the email is spam or invalid, remove it with exim -Mrm <message-id> after backing up the queue list.

    Q: How long does Exim keep emails in queue before removing them?

    By default, Exim retains emails in queue for several days depending on the retry configuration set in WHM. Default retry rules typically attempt resending several times within a specific timeframe before giving up. Emails that exceed the retry limit remain in queue until manually flushed or until the retention period expires. You can check retry configuration in WHM under Exim Configuration Manager, Advanced Editor, in the retry rules section. For more detailed settings, read our Exim Retry Configuration Guide.

    Author: Syslog Solutions — NOC & Server Management Team. We handle 500+ servers daily, from shared hosting to enterprise dedicated infrastructure.