I have seen this topic many times and I don’t understand what I’m doing wrong.
I created a fresh installation via Docker Compose (Ghost 6.50.0). I saw contradicting information on where to put the SMTP mail credentials, i.e. whether to put them into the .env file or the compose.yml file. Right now, I have the exact same details in both files, which might be causing these issues? Should it be in .env or compose.yml or even some place else?
I had an old config.production.json file from my old installation (Ghost 5). The SMTP credentials used to go there, so they were in this file too. I removed them so the file only has the original
"mail": {
"transport": "SMTP"
}
in it. I then renamed the file to see if it was the one causing issues and it seems instead of a timeout, it now doesn’t work right away.
This is from my .env
# SMTP Email (https://ghost.org/docs/config/#mail)
# Transactional email is required for logins, account creation (staff invites), password resets and other features
# This is not related to bulk mail / newsletter sending
mail__transport=SMTP
mail__options__host=mail.eroticmythology.com
mail__options__port=587
mail__options__secure="false"
mail__options__auth__user=support@eroticmythology.com
mail__options__auth__pass=password
What’s the error messages? Some VPS hosts block outbound smtp ports, but the Ghost logs should help you sort out whether the problem is an incorrect password, wrong protocol, or just timeout/can’t connect (which would be consistent with your host blocking you).
{"name":"Log","hostname":"05b4a8813590","pid":1,"level":50,"version":"6.50.0","err":{"id":"e317fd90-78b5-11f1-b620-b5a99c368423","domain":"https://eroticmythology.com","code":"ETIMEDOUT","name":"EmailError","statusCode":500,"level":"normal","message":"Failed to send email. Reason: Greeting never received.","help":"\"Please see https://ghost.org/docs/config/#mail for instructions on configuring email.\"","stack":"Error: Greeting never received\n at createMailError (/var/lib/ghost/versions/6.50.0/core/server/services/mail/ghost-mailer.js:91:12)\n at SMTPConnection._formatError (/var/lib/ghost/versions/6.50.0/node_modules/.pnpm/nodemailer@9.0.1/node_modules/nodemailer/lib/smtp-connection/index.js:905:19)\n at SMTPConnection._onError (/var/lib/ghost/versions/6.50.0/node_modules/.pnpm/nodemailer@9.0.1/node_modules/nodemailer/lib/smtp-connection/index.js:886:20)\n at Timeout.<anonymous> (/var/lib/ghost/versions/6.50.0/node_modules/.pnpm/nodemailer@9.0.1/node_modules/nodemailer/lib/smtp-connection/index.js:820:22)\n at listOnTimeout (node:internal/timers:585:17)\n at process.processTimers (node:internal/timers:521:7)","hideStack":false},"msg":"Failed to send email. Reason: Greeting never received.","time":"2026-07-05T21:10:01.963Z","v":0}
It seems like I may have made a formatting error but I doubt I should go and look for it inside the index.js
Maybe it’s a timeout issue because the port is blocked, as you say, but I believe it worked in the past.
Just because your firewall is open, doesn’t mean your host isn’t blocking it still.
Also, I usually suggest putting secrets in .Env due to compose.yml having secrets leak vulnerability in plaintext
Yes, you and @Cathy_Sarisky are right, of course, and I sent a request to my provider to ask if outbound SMTP is blocked. It’s possible they closed it only recently because there was some mail-related vulnerability.
Also thanks a bunch for telling me about the leak potential of compose.yml, I’ll promptly remove the credentials from there. I had originally put it in .env but while trying to solve the issue, I saw a post where it was recommended to put it in compose.yml instead so I tried both.
I’m now kinda hoping it’s the blocked outbound mail because that would be braindead on my part but the easiest fix
Thank you, I have deleted the settings from the composer.yml.
I am using the service on my VPS, I think it is exim4. My provider confirmed that the ports are not blocked. My provider checked the email settings as well and successfully reached the SMTP server.
But I think I have found the error. Somewhere, “noreply@eroticmythology.com” is set as the reply address. I’m not sure where this happened because it’s not in the .env but this email address really did not exist, probably prompting the 500 error. I added “noreply” as an alias and now it seems to work.