SMTP Errors – 550 vs 450

Well I got a lesson in properly configuring your e-mail server’s error messages. Since setting up postfix as a anti-spam and anti-virus gateway for my exchange system (see my article Postfix as proxy to exchange server), I had left the option
soft_bounce = yes
enabled in my postfix configuration.

This worked fine for months. However, I was then “joe jobbed” – which means that some spammer used my domain name as the “from” or “reply to” address on their e-mails. This causes a flood of e-mails from mail servers, which messages such as, no user exists, this account has been deleted, etc. These e-mails are completely valid and authentic responses from e-mail servers.

Now – it is my personal opinion that mail servers should reject connections to users who are not real – not generate more messages and bandwidth sending out their rejection response. But I understand why some e-mail providers wish to keep this option on, and I think Exchange has it on by default. So trying to change peoples minds is not going to work – we need to deal with these rejection messages responsibly.

Here is where my server configuration showed its flaws. Here is the official definition of the 450 and 550 error messages:

450 Requested mail action not taken: mailbox unavailable (e.g., mailbox busy)
550 Requested action not taken: mailbox unavailable (e.g., mailbox not found, no access, or command rejected for policy reasons)

The difference between the two error codes is not really apparent at first glance. However, 400 level commands tells the remote servers that there is a temporary error, and it should try again later. How much later depends on each server’s settings. The 500 level commands tell the remote server that it is a permanent failure, and it should not try again later.

In the case of a joe job – you have thousands of servers responding to your server that addresses can’t be found (or any other error). When you have each of those servers “retrying” their e-mail connects every 10 minutes or so, your server will quickly find itself rejecting a whole lot of messages.

Fortunately, the fix is easy. Fix your server to respond with a 550 instead of 450. Look at the change in the graph below – almost immediately after I switched to the 550 message:

SMTP 450 vs 550 rejection rate

You can see the benefits of keeping the 550 message. In postfix, the change is simple, change the soft_bounce line to:

soft_bounce = no

You can also customize your rejection codes for particular errors as below.

unknown_local_recipient_reject_code = 550
unknown_address_reject_code = 550
unknown_client_reject_code = 550
unknown_hostname_reject_code = 550
unknown_relay_recipient_reject_code = 550
unknown_virtual_alias_reject_code = 550
unknown_virtual_mailbox_reject_code = 550
unverified_recipient_reject_code = 550
unverified_sender_reject_code = 550

For more codes: Postconf manual

Zabbix remote ping check

I’ve had my Zabbix install set up to notify me if the remote server has a high ping using this expression:


The problem is, if your network is congested, it can really hit often. I recommend moving the failed ping average up to 500, and adding another trigger:


This checks for no ping within 120 seconds (or 2 minutes) so it gives you a better idea if the host is "down" or just seeing a high ping latency.