Issue Summary
- Setting up SMTP transactional email. Fails to verify with ESOCKET.
- Expected: Successful transactional email.
Steps to Reproduce
- Deploy docker ghost:6
- Configure SMTP, attempt to verify.
Setup information
Ghost Version
Docker - ghost:6
Node.js Version
Node.js v22.20.0.
How did you install Ghost?
Compose config with docker image
Provide details of your host & operating system
Underlying ubuntu 22 at the moment
Database type
MySQL 8
Browser & OS version
Include if reporting frontend bugs.
Relevant log / error output
```
2025-10-21T15:46:49.004611480Z Error Code:
2025-10-21T15:46:49.004615946Z ESOCKET
2025-10-21T15:46:49.004619731Z
2025-10-21T15:46:49.004623265Z ----------------------------------------
2025-10-21T15:46:49.004627014Z
2025-10-21T15:46:49.004630656Z EmailError: Failed to send email. Please check your site configuration and try again.
2025-10-21T15:46:49.004634557Z at Object.sendAuthCodeToUser (/var/lib/ghost/versions/6.3.1/core/server/services/auth/session/session-service.js:284:19)
2025-10-21T15:46:49.004638879Z at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
2025-10-21T15:46:49.004642730Z at async Object.createSession (/var/lib/ghost/versions/6.3.1/core/server/services/auth/session/middleware.js:16:17)
```
I’ve been going back and forth with my SMTP provider. The latest they’ve provided is that the handshake for the mailer skips auth commands after the initial connection. I’ve looking for similar bugs and found mention of gSuite SMTP setup, which I’m specifically trying to migrate away from at the moment. I may be trying yet another mail provider to get around this. What’s going on with this SMTP handshake?
If you want help, please share your (lightly redacted) docker compose file showing all mail__ settings.
And which Docker image are you using? The “Docker Official” one from Docker, or the one in the tryghost/ghost-docker repo?
It will probably also be helpful to name your hosting environment if self hosting, and the specific mail provider you’re trying to deliver to, in case you’re hitting a known quirk.
If I had to take a totally wild guess at the actual problem: Your host is blocking outbound SMTP traffic on the port you’re using. But that’s a completely random guess, and you haven’t provided enough information.
Thank you for your attention and reply.
Outbound SMTP is not being blocked, unless specific components of the exchange are being blocked.
The compose:
version: '3.8'
networks:
coolify:
external: true
services:
ghost:
image: 'ghost:6'
volumes:
- 'ghost-content-data:/var/lib/ghost/content'
environment:
- 'SERVICE_FQDN_GHOST_2368=name.com'
- 'url=https://name.com'
- database__client=mysql
- database__connection__host=mysql
- database__connection__user=$SERVICE_USER_MYSQL
- database__connection__password=$SERVICE_PASSWORD_MYSQL
- 'database__connection__database=${MYSQL_DATABASE-ghost}'
- mail__options__port=587
- mail__options__service=Mailgun
- mail__options__host=smtp.protonmail.ch
- mail__transport=SMTP
- mail__from='name <name@name.com>'
- mail__options__from='name <name@name.com>'
- mail__options__secureConnection=true
- mail__options__auth__user='name@name.com'
- mail__options__auth__pass='key'
depends_on:
mysql:
condition: service_healthy
healthcheck:
test:
- CMD
- echo
- ok
interval: 5s
timeout: 20s
retries: 10
networks:
- coolify
mysql:
image: 'mysql:8.0'
volumes:
- 'ghost-mysql-data:/var/lib/mysql'
environment:
- 'MYSQL_USER=${SERVICE_USER_MYSQL}'
- 'MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL}'
- 'MYSQL_DATABASE=${MYSQL_DATABASE}'
- 'MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}'
healthcheck:
test:
- CMD
- mysqladmin
- ping
- '-h'
- 127.0.0.1
interval: 5s
timeout: 20s
retries: 10
networks:
- coolify
You will notice the image. I have tested extensively with both the hub images, and the tryghost images.
My self hosting environment has changed significantly while testing this as well, from running in the localhost server defined in coolify hosted on a VPS in digital ocean, to app servers on bare metal in my own home.
So Digital Ocean routinely blocks outbound SMTP on most ports including 587. Many many home ISPs also block SMTP. So sorry if it was the wrong guess. I’m wasn’t sure what your screenshot is. Is that something your mail host sent you?
I don’t think you want to specify the mail service as Mailgun if you’re connecting to protonmail. Presumably your user and pass are the ones protonmail gave you, right?
As I understood it the mail service is simply a text label, but I’ve also specified “Proton,” and left it blank. The docs made no specific mention.
If SMTP were blocked at a protocol or port level, my host would not be seeing any portion of a handshake, no? A mail in a box instance has been working with no issues for years from the same address space. Mail on DO is a nightmare yes, I have experience with that. Yes the user and pass are correctly set as a user with an issued API key, matching the RECV FROM address. They had previously been dropping traffic due to that misconfiguration on my end. I know traffic is flowing to them and I trust their response about a protocol hiccup.
yes that screenshot is indeed from my provider. They took a while to get back to this, I assume they looked at some pretty granular logs. I have yet to get into the nodemailer code. I was hoping this topic may surface an expert before I start that process myself.