Frequently asked questions
Where to ask questions?
First, please read this FAQ to check if your question is listed here. Simple questions best fit in our Matrix room. For more complex questions, you can always open a new issue on GitHub. We actively monitor the issues list.
My installation is broken!
We’re sorry to hear that. Please check for common mistakes and troubleshooting advice in the Technical issues section of this page.
I think I found a bug!
I want a new feature or enhancement!
Great! We are always open for suggestions. We currently maintain two tags:
Enhancement issues: Typically used for optimization of features in the project.
Feature request issues: For implementing new functionality, plugins and applications.
Please check if your idea (or something similar) is already mentioned there. If there is one open, you can choose to vote with a thumbs up, so we can estimate the popular demand. Please refrain from writing comments like “me too” as it clobbers the actual discussion.
If you can’t find anything similar, you can open a new issue. Please also share (where applicable):
Use case: how does this improve the project?
Any research done on the subject. Perhaps some links to upstream website, reference implementations etc.
Why does my feature/bug take so long to solve?
You should be aware that creating, maintaining and expanding a mail server distribution requires a lot of effort. Mail servers are highly exposed to hacking attempts, open relay scanners, spam and malware distributors etc. We need to work in a safe way and have to prevent pushing out something quickly.
TODO: Move the next section into the contributors part of docs We currently maintain a strict work flow:
Someone writes a solution and sends a pull request;
We use Github actions for some very basic building and testing;
The pull request needs to be code-reviewed and tested by at least two members from the contributors team.
Please consider that this project is mostly developed in people their free time. We thank you for your understanding and patience.
I would like to donate (for a feature)
We maintain a Communtity Bridge project through which you can donate. This budget will be used to pay for development of features, mentorship and hopefully future events. Contributing companies or individuals can be paid from this budget to support their development efforts.
We are also looking into GitHub’s integrated sponorship program for individual contributors. Once those become available, we will add them to the project.
In this section we are trying to cover the most common problems our users are having. If your issue is not listed here, please consult issues with the troubleshooting tag.
Changes in .env don’t propagate
Variables are sent to the containers at creation time. This means you need to take the project down and up again. A container restart is not sufficient.
docker-compose down && \ docker-compose up -d
Issue reference: 615.
My emails are getting defered, what can I do?
Emails are asynchronous and it’s not abnormal for them to be defered sometimes. That being said, Mailu enforces secure connections where possible using DANE and MTA-STS, both of which have the potential to delay indefinitely delivery if something is misconfigured.
If delivery to a specific domain fails because their DANE records are invalid or their TLS configuration inadequate (expired certificate, …), you can assist delivery by downgrading the security level for that domain by creating an override at
overrides/postfix/tls_policy.map as follow:
domain.example.com may domain.example.org encrypt
The syntax and options are as described in postfix’s documentation. Re-creating the smtp container will be required for changes to take effect.
403 - Access Denied Errors
While this may be due to several issues, check to make sure your
DOMAIN= entry is the first entry in your
TLS certificate issues
When there are issues with the TLS/SSL certificates, Mailu denies service on secure ports. This is a security precaution. Symptoms are:
403 browser errors;
These issues are typically caused by four scenarios:
TLS_FLAVOR=letsencrypt, it might be that the certbot script is not capable of obtaining the certificates for your domain. See letsencrypt issues
TLS_FLAVOR=certs, certificates are supposed to be copied to
/mailu/certs. Using an external
letsencryptprogram, it tends to happen people copy the whole
letsencrypt/livedirectory containing symlinks. Symlinks do not resolve inside the container and therefore it breaks the TLS implementation.
In order to determine the exact problem on TLS / Let’s encrypt issues, it might be helpful to check the logs.
docker-compose logs front | less -R docker-compose exec front less /var/log/letsencrypt/letsencrypt.log
Port 80 not reachable from outside.
Faulty DNS records: make sure that all
HOSTNAMEShave A (IPv4) and AAAA (IPv6) records, pointing the the
DNS cache not yet expired. It might be that old / faulty DNS records are stuck in a cache en-route to letsencrypt’s server. The time this takes is set by the
TTLfield in the records. You’ll have to wait at least this time after changing the DNS entries. Don’t keep trying, as you might hit rate-limits.
As mentioned above, care must be taken not to copy symlinks to the
The wrong way!:
cp -r /etc/letsencrypt/live/domain.com /mailu/certs
The right way!:
mkdir -p /mailu/certs cp /etc/letsencrypt/live/domain.com/privkey.pem /mailu/certs/key.pem cp /etc/letsencrypt/live/domain.com/fullchain.pem /mailu/certs/cert.pem
How do I activate DKIM and DMARC?
Go into the Domain Panel and choose the Domain you want to enable DKIM for. Click the first icon on the left side (domain details). Now click on the top right on the “Regenerate Keys” Button. This will generate the DKIM and DMARC entries for you.
Issue reference: 102.
Do you support Fail2Ban?
Fail2Ban is not included in Mailu. Fail2Ban needs to modify the host’s IP tables in order to
ban the addresses. We consider such a program should be run on the host system and not
inside a container. The
front container does use authentication rate limiting to slow
down brute force attacks. The same applies to login attempts via the single sign on page.
We do provide a possibility to export the logs from the
front service and
Admin service to the host.
front container logs failed logon attempts on SMTP, IMAP and POP3.
Admin``container logs failed logon attempt on the single sign on page.
For this you need to set ``LOG_DRIVER=journald or
syslog, depending on the log
manager of the host. You will need to setup the proper Regex in the Fail2Ban configuration.
Below an example how to do so.
If you use a reverse proxy in front of Mailu, it is vital to set the environment variables REAL_IP_HEADER and REAL_IP_FROM. Without these environment variables, Mailu will not trust the remote client IP passed on by the reverse proxy and as a result your reverse proxy will be banned. See the [configuration reference for more information.
Assuming you have a working Fail2Ban installation on the host running your Docker containers, follow these steps:
In the mailu docker-compose set the logging driver of the front container to journald; and set the tag to mailu-front
logging: driver: journald options: tag: mailu-front
Add the /etc/fail2ban/filter.d/bad-auth.conf
# Fail2Ban configuration file [Definition] failregex = .* client login failed: .+ client:\ <HOST> ignoreregex = journalmatch = CONTAINER_TAG=mailu-front
Add the /etc/fail2ban/jail.d/bad-auth.conf
[bad-auth] enabled = true backend = systemd filter = bad-auth bantime = 604800 findtime = 300 maxretry = 10 action = docker-action
The above will block flagged IPs for a week, you can of course change it to you needs.
In the mailu docker-compose set the logging driver of the Admin container to journald; and set the tag to mailu-admin
logging: driver: journald options: tag: mailu-admin
Add the /etc/fail2ban/filter.d/bad-auth-sso.conf
# Fail2Ban configuration file [Definition] failregex = .* Login failed for .+ from <HOST>. ignoreregex = journalmatch = CONTAINER_TAG=mailu-admin
Add the /etc/fail2ban/jail.d/bad-auth-sso.conf
[bad-auth-sso] enabled = true backend = systemd filter = bad-auth-sso bantime = 604800 findtime = 300 maxretry = 10 action = docker-action
The above will block flagged IPs for a week, you can of course change it to you needs.
Add the /etc/fail2ban/action.d/docker-action.conf
[Definition] actionstart = iptables -N f2b-bad-auth iptables -A f2b-bad-auth -j RETURN iptables -I DOCKER-USER -p tcp -m multiport --dports 1:1024 -j f2b-bad-auth actionstop = iptables -D DOCKER-USER -p tcp -m multiport --dports 1:1024 -j f2b-bad-auth iptables -F f2b-bad-auth iptables -X f2b-bad-auth actioncheck = iptables -n -L DOCKER-USER | grep -q 'f2b-bad-auth[ \t]' actionban = iptables -I f2b-bad-auth 1 -s <ip> -j DROP actionunban = iptables -D f2b-bad-auth -s <ip> -j DROP
Using DOCKER-USER chain ensures that the blocked IPs are processed in the correct order with Docker. See more in: https://docs.docker.com/network/iptables/
Configure and restart the Fail2Ban service
Make sure Fail2Ban is started after the Docker service by adding a partial override which appends this to the existing configuration.
sudo systemctl edit fail2ban
Add the override and save the file.
Restart the Fail2Ban service.
sudo systemctl restart fail2ban
Users can’t change their password from webmail
All users have the abilty to login to the admin interface. Non-admin users have only restricted funtionality such as changing their password and the spam filter weight settings.
Issue reference: 503.
rspamd: DNS query blocked on multi.uribl.com
This usually relates to the DNS server you are using. Most of the public servers block this query or there is a rate limit. In order to solve this, you most probably are better off using a root DNS resolver, such as unbound. This can be done in multiple ways:
Use the Mailu/unbound container. This is an optional include when generating the
docker-compose.ymlfile with the setup utility.
Setup unbound on the host and make sure the host’s
/etc/resolve.confpoints to local host. Docker will then forward all external DNS requests to the local server.
Set up an external DNS server with root resolving capabilities.
In any case, using a dedicated DNS server will improve the performance of your mail server.
Can I learn ham/spam messages from an already existing mailbox?
Mailu is supporting automatic spam learning for messages moved to the Junk mailbox. Any email moved from the Junk Folder will learnt as ham.
If you already have an existing mailbox and want Mailu to learn them all as ham messages, you might run rspamc from within the dovecot container:
rspamc -h antispam:11334 -P mailu -f 13 fuzzy_add /mail/user\@example.com/.Ham_Learn/cur/
This should learn every file located in the
Ham_Learn folder from firstname.lastname@example.org
Likewise, to lean all messages within the folder
Spam_Learn as spam messages :
rspamc -h antispam:11334 -P mailu -f 11 fuzzy_add /mail/user\@example.com/.Spam_Learn/cur/
Issue reference: 1438.
Is there a way to support more (older) ciphers?
You will need to rewrite the tls.conf template of the front container in core/nginx.
You can set the protocols as follow:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers <list of ciphers>;
After applying the change, you will need to rebuild the image and use it in your deployment.
We strongly advice against downgrading the TLS version and ciphers, please upgrade your client instead! We will not support a more standard way of setting this up.
Why does Compose complain about the yaml syntax
In many cases, Docker Compose will complain about the yaml syntax because it is too old. It is especially true if you installed Docker Compose as part of your GNU/Linux distribution package system.
Unless your distribution has proper up-to-date packages for Compose, we strongly advise that you install it either:
from the Docker-CE repositories along with Docker CE itself,
from PyPI using pip install docker-compose or
from Github by downloading it directly.
Detailed instructions can be found at https://docs.docker.com/compose/install/
Issue reference: 853.
Why are still spam mails being discarded?
Disabling antispam in the user settings actually disables automatic classification of messages as spam and stops moving them to the junk folder. It does not stop spam scanning and filtering.
Therefore, messages still get discarded if their spam score is so high that the antispam finds them unfit for distribution. Also, the antispam headers are still present in the message, so that mail clients can display it and classify based on it.
Issue reference: 897.
Why is SPF failing while properly setup?
Very often, SPF failure is related to Mailu sending emails with a different IP address than the one configured in the env file.
This is mostly due to using a separate IP address for Mailu and still having masquerading nat setup for Docker, which results in a different outbound IP address. You can simply check the email headers on the receiving side to confirm this.
If you wish to explicitely nat Mailu outbound traffic, it is usually easy to source-nat outgoing SMTP traffic using iptables :
iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 25 -j SNAT --to <your mx ip>
Issue reference: 1090.
A user gets
Sender address rejected: Access denied. Please check the
message recipient […] and try again even though the sender is legitimate?
First, check if you are really sure the user is a legitimate sender, i.e. the registered user is authenticated successfully and own either the account or alias he/she is trying to send from. If you are really sure this is correct, then the user might try to errornously send via port 25 insteadof the designated SMTP client-ports. Port 25 is meant for server-to-server delivery, while users should use port 587 or 465.
The admin container won’t start and its log says
Critical: your DNS resolver isn't doing DNSSEC validation
Since v1.9, Mailu requires a validating DNSSEC enabled DNS resolver. To check whether your DNS resolver (and its upstream) fits the requirements you can use the following command and see whether the AD flag is present in the reply:
dig @<ip> +adflag example.org A
We recommend that you run your own DNS resolver (enable unbound and update your docker-compose.yml when you update from older versions) instead of relying on publicly available ones. It’s better security-wise (you don’t have to trust them) and RBLs used by rspamd are known to rate-limit per source-ip address.
We have seen a fair amount of support requests related to the following:
dnsmasq won’t forward DNSSEC results unless instructed to do so. If you are running openwrt or pi-hole, you do need to enable DNSSEC.
coredns has a bug that we have now worked around