Docs / GitLab

Configure GitLab SMTP (self-managed)

A self-managed GitLab sends mail for sign-up confirmations, password resets, merge request and pipeline notifications. The Linux package defaults to a local sendmail, and the Docker image has no mail server at all — so unless you point it at an SMTP relay, those emails either go nowhere or arrive unauthenticated. This guide covers the Linux package (Omnibus) and the official Docker image, which reads the same settings.

✓
You can get them on the token management page. For security reasons, a token is shown only once — at the moment it is created.

SMTP connection settings

SettingValue
SMTP hostsmtp.postwing.app
Port587
EncryptionSTARTTLS (the connection is upgraded to TLS before login)
UsernameThe login of an SMTP token for your domain
PasswordThe password of that token — shown once, when the token is created
ℹ
Every mode is also available on a high port: 8465 (SSL/TLS), 8587 (STARTTLS) and 8025 (plain). Many hosting providers and clouds block outbound 25, 465 and 587 — if the connection times out, switch to the matching high port.

Configure gitlab.rb

Add these lines to /etc/gitlab/gitlab.rb. gitlab_email_from is the address every notification comes from, so it must be on your verified domain:

/etc/gitlab/gitlab.rb
# /etc/gitlab/gitlab.rb
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.postwing.app"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "token-login@your-domain.com"
gitlab_rails['smtp_password'] = "your-token-password"
gitlab_rails['smtp_domain'] = "your-domain.com"
gitlab_rails['smtp_authentication'] = "plain"
gitlab_rails['smtp_enable_starttls_auto'] = true   # STARTTLS on 587
gitlab_rails['smtp_tls'] = false                   # true only for port 465
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'

gitlab_rails['gitlab_email_from'] = 'gitlab@your-domain.com'
gitlab_rails['gitlab_email_display_name'] = 'GitLab'
gitlab_rails['gitlab_email_reply_to'] = 'noreply@your-domain.com'
⚠
Port 587 needs smtp_enable_starttls_auto = true and smtp_tls = false. Port 465 needs smtp_tls = true. Setting both to true stops GitLab from sending at all. Avoid a single quote in the password — GitLab's docs warn that Ruby and YAML string delimiters break config processing.

For port 465 instead:

ruby
# Port 465 (implicit TLS) instead of 587
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_enable_starttls_auto'] = false

Apply the configuration:

bash
sudo gitlab-ctl reconfigure

Docker

The official image accepts any gitlab.rb setting through GITLAB_OMNIBUS_CONFIG. It is evaluated on every start and never written to gitlab.rb, so keep it in the compose file and run docker compose up -d after changing it:

docker-compose.yml
# docker-compose.yml
services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    hostname: gitlab.your-domain.com
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.your-domain.com'
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['smtp_address'] = "smtp.postwing.app"
        gitlab_rails['smtp_port'] = 587
        gitlab_rails['smtp_user_name'] = "token-login@your-domain.com"
        gitlab_rails['smtp_password'] = "your-token-password"
        gitlab_rails['smtp_domain'] = "your-domain.com"
        gitlab_rails['smtp_authentication'] = "plain"
        gitlab_rails['smtp_enable_starttls_auto'] = true
        gitlab_rails['gitlab_email_from'] = 'gitlab@your-domain.com'

Alternatively, edit /etc/gitlab/gitlab.rb inside the container (docker exec -it gitlab editor /etc/gitlab/gitlab.rb) and run docker restart gitlab — GitLab reconfigures itself on start.

Send a test email

There is no test button in the Admin area; use the Rails console (in Docker, prefix it with docker exec -it gitlab):

ruby
sudo gitlab-rails console

# at the console prompt
Notify.test_email('you@example.com', 'GitLab SMTP test', 'It works.').deliver_now

If nothing arrives, check ActionMailer::Base.delivery_method in the same console — it must return :smtp — and ActionMailer::Base.smtp_settings for the values GitLab actually loaded.

Keep the credentials encrypted

With encrypted configuration enabled, the SMTP login and password can move out of gitlab.rb into an encrypted file. Remove smtp_user_name and smtp_password from gitlab.rb afterwards and reconfigure:

bash
sudo gitlab-rake gitlab:smtp:secret:edit EDITOR=vim

# contents of the encrypted file
user_name: 'token-login@your-domain.com'
password: 'your-token-password'

Troubleshooting

ErrorCause and fix
SSL_connect returned=1 ... wrong version numbersmtp_tls = true on port 587. Use STARTTLS there, or switch to 465.
:enable_starttls and :tls are mutually exclusiveBoth flags are true. Set the one that does not match the port to false.
Net::OpenTimeout Outbound port blocked — set smtp_port to 8587, or 8465 with smtp_tls.
535 Authentication failedWrong token login or password.
Console test works, notifications do not An external Sidekiq without the SMTP settings, or routing rules that skip the mailers queue.
Sender rejected or mail in spamgitlab_email_from is not on your verified domain.

Frequently asked questions

Where are the SMTP settings in GitLab?

On a self-managed Linux package (Omnibus) install they are the gitlab_rails['smtp_*'] keys in /etc/gitlab/gitlab.rb. There is no SMTP form in the Admin area. After editing the file, run sudo gitlab-ctl reconfigure to apply it.

What is the difference between smtp_tls and smtp_enable_starttls_auto?

smtp_enable_starttls_auto upgrades a plain connection with STARTTLS — use it with port 587. smtp_tls opens an encrypted connection from the first byte — use it with port 465. They are mutually exclusive: with both set to true, GitLab refuses to send.

How do I send a test email from GitLab?

Start sudo gitlab-rails console and run Notify.test_email('you@example.com', 'Subject', 'Body').deliver_now. Any SMTP error is printed straight to the console, which is the fastest way to see what is wrong.

How do I configure SMTP for GitLab in Docker?

Put the same gitlab_rails lines in the GITLAB_OMNIBUS_CONFIG environment variable, or edit /etc/gitlab/gitlab.rb inside the container and run docker restart gitlab. GITLAB_OMNIBUS_CONFIG is evaluated on every start and is not written to gitlab.rb, so it must stay in your compose file.

Why does GitLab fail with 'wrong version number'?

The TLS mode does not match the port. Port 587 starts unencrypted and needs smtp_enable_starttls_auto = true with smtp_tls = false; port 465 needs smtp_tls = true. Fix the pair and run gitlab-ctl reconfigure.

Why do GitLab emails still not go out after the test works?

Most GitLab mail is sent by Sidekiq from the mailers queue. If Sidekiq runs on a separate server, that server's gitlab.rb needs the same SMTP settings; if you use Sidekiq routing rules, make sure the mailers queue is still processed.

Next steps