Emails not being sent from self-hosted Ghost instance

Issue Summary

Emails are not being sent from Ghost.

I think I’ve follow the documentation correctly, but I may have missed something. In addition to the SMTP details below I’ve also updated the /settings/labs/members Mailgun region, domain and API Key to match those provided in my MailGun Account.

How was Ghost installed and configured?

Installed onto a Digital Ocean droplet using the official one-click-deployment image.

Of note the only configuration that has changed from the one-click-deployment was the /var/www/ghost/config.production.json file which has had the mail node updated as per the documation.

"mail": {
    "transport": "SMTP",
    "options": {
    "service": "Mailgun",
    "host": "",
    "port": 587,
    "secureConnection": true,
    "auth": {
        "user": "REDACTED",
        "pass": "REDACTED"

I’ve tried both the secure and non-secure examples shown in the docs and neither make any difference to the issue at hand.

What Node version, database, OS & browser are you using?

Node: v12.18.0
OS: Ubuntu
Browser: Chrome

What errors or information do you see in the console?

No related errors in the following log files:

  • /var/www/ghost/content/logs/https___a7d47973106c4240b3baca79f3ef5a00_tk_production.log
  • /var/www/ghost/content/logs/https___a7d47973106c4240b3baca79f3ef5a00_tk_production.error.log

What steps could someone else take to reproduce the issue you’re having?

In theory, following through the instructions in the droplet image and configuring MailGun per the docs should re-create this issue each time.

Additional steps taken:

  • Port 587 opened for MailGun
  • Ghost restarted to ensure config changes are picked up
  • Digital Ocean DNS configuration inline with the entries expected by MailGun

If I manually verify sending an email to MailGun via SMTP based on their own quickstart guide then it works as expected and I get the email through to my inbox:

./swaks --auth \
	--server \
	--au postmaster@redacted \
	--ap REDACTED \
	--h-Subject: "Testing" \
	--body 'Standard test to verify.'

The above command produces the following output (truncated for brevity):
=== Trying org:25…
=== Connected to org.
← 220 Mailgun Influx ready

← 250 Great success
← 221 See you later. Yours truly, Mailgun
=== Connection closed with remote host.

@MichaelSearson the settings in config.production.json are for transactional email, you can set this up with Mailgun or any other email provider. Transactional emails are staff invites, member signups, etc.

Bulk email for newsletters is only available via Mailgun. You need to configure that by supplying an API Key in the members settings area.

Docs are here

@Kevin thanks for the quick response and clarification around the settings!

As mentioned in the intial post I have configured the API settings in Ghost:

And as per the hyperlinks in the screenshot I’ve copied over the mailgun domain and API Key. But that hasn’t made any difference.

Something that I have just noticed though. In MailGun’s examples of manually calling the API the URL structure is In Ghost, I’ve just provided:

Should I append the /messages route here as well? Or does Ghost take care of this for me?

If I manually call the API with the same credentials I get back a: "message": "Queued. Thank you." response so I must be doing something wrong with Ghost.

The Mailgun domain isn’t correct, it should only be a domain rather than a full URL. Try putting in as the domain instead.

Aha! Gotcha - managed to overlook that! It’s all working as expected now. Thank you! :smiley: