Transactional mails on Local Ghost (non docker)

Hello,

I have setup local docker on windows and am developing a theme for the client. All is okay, apart from one thing - transactional emails. I just can’t send them. I tried various guides here on forum, but none of them seems to work.

This is my config.development.json in main ghost directory

{
  "url": "http://localhost:2368/",
  "server": {
    "port": 2368,
    "host": "127.0.0.1"
  },
  "database": {
    "client": "sqlite3",
    "connection": {
      "filename": "C:\\adapt\\ghost\\content\\data\\ghost-local.db"
    }
  },
  "mail": {
    "transport": "SMTP",
    "options": {
      "service": "Google",
      "host": "smtp.gmail.com",
      "port": 587,
      "auth": {
        "user": "[my-gmail]",
        "pass": "[my-psw]"
      }
    }
  },
  "logging": {
    "transports": [
      "file",
      "stdout"
    ]
  },
  "process": "local",
  "paths": {
    "contentPath": "C:\\adapt\\ghost\\content"
  }
}

When I first edited it while still running ghost and just restarted and tried sending mails I got error: Failed to send email. Reason: self-signed certificate in certificate chain.

Now when I stopped it and try to start, it won’t even start.

Running in development mode

√ Checking system Node.js version - found v20.18.0
√ Checking current folder permissions
× Validating config
√ Checking memory availability
√ Checking binary dependencies
One or more errors occurred.

1) Validating config

Error detected in the development configuration.

Message: Invalid mail service
Configuration Key(s): mail.options.service
Current Value(s): Google

Help: Run `ghost config <key> <new value>` for each key to fix the issue.


Debug Information:
    OS: Microsoft Windows 10 Home, v10.0.19045
    Node Version: v20.18.0
    Ghost Version: 5.109.6
    Ghost-CLI Version: 1.26.1
    Environment: development

I tried googling, searching, doing whatever, I can’t figure it out. The documentation is very lacking. And yes my gmail has two-factor enabled.

Without mail I can’t test any of the member functionality which suck tremendously.

You may want to look at maildev, which is a nice way to ‘capture’ those emails during local development.

Here’s my doc on using gmail in local development:

I think that you need to remove the ‘service’ line.

1 Like

Thanks, i’ve actually stumbled upon your post.

I tried changing the service line - so it starts, but when sign up I get 500 internal error

and logs state

{"name":"Log","hostname":"DESKTOP-R567VF2","pid":28888,"level":30,"version":"5.109.6","req":{"meta":{"requestId":"fabb5019-12db-41a2-9417-1d701181c72a","userId":null},"url":"/api/integrity-token/","method":"GET","originalUrl":"/members/api/integrity-token/","params":{},"headers":{"host":"localhost:2368","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36","sec-ch-ua":"\"Not(A:Brand\";v=\"99\", \"Google Chrome\";v=\"133\", \"Chromium\";v=\"133\"","sec-ch-ua-mobile":"?0","accept":"*/*","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:2368/lnd-v0-18-5-beta/","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en-GB,en;q=0.9,en-US;q=0.8,lt;q=0.7","cookie":"**REDACTED**"},"query":{}},"res":{"_headers":{"x-powered-by":"Express","cache-control":"no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0","access-control-allow-origin":"*"},"statusCode":200,"responseTime":"2ms"},"msg":"","time":"2025-02-25T19:54:49.159Z","v":0}
{"name":"Log","hostname":"DESKTOP-R567VF2","pid":28888,"level":40,"version":"5.109.6","msg":"Hey there,\n\nTap the link below to complete the signup process for No Bullshit Bitcoin, and be automatically signed in:\n\nhttp://localhost:2368/members/?token=EFZZAwj-bVjSTKsGlFDMeVP7dXyT3B-i&action=signup&r=http%3A%2F%2Flocalhost%3A2368%2Flnd-v0-18-5-beta%2F\n\nFor your security, the link will expire in 24 hours time.\n\nSee you soon!\n\n---\n\nSent to services@petrosius.me\nIf you did not make this request, you can simply delete this message. You will not be signed up, and no account will be created for you.","time":"2025-02-25T19:54:49.662Z","v":0}
{"name":"Log","hostname":"DESKTOP-R567VF2","pid":28888,"level":50,"version":"5.109.6","err":{"id":"5f295fd0-f3b2-11ef-8771-79c6a52f886d","domain":"http://localhost:2368/","code":"ESOCKET","name":"EmailError","statusCode":500,"level":"normal","message":"Failed to send email. Reason: self-signed certificate in certificate chain.","help":"\"Please see https://ghost.org/docs/config/#mail for instructions on configuring email.\"","stack":"Error: self-signed certificate in certificate chain\n    at createMailError (C:\\adapt\\ghost\\versions\\5.109.6\\core\\server\\services\\mail\\GhostMailer.js:81:12)\n    at TLSSocket.onConnectSecure (node:_tls_wrap:1677:34)\n    at TLSSocket.emit (node:events:519:28)\n    at TLSSocket._finishInit (node:_tls_wrap:1076:8)\n    at ssl.onhandshakedone (node:_tls_wrap:862:12)","hideStack":false},"msg":"Failed to send email. Reason: self-signed certificate in certificate chain.","time":"2025-02-25T19:54:49.805Z","v":0}
{"name":"Log","hostname":"DESKTOP-R567VF2","pid":28888,"level":50,"version":"5.109.6","req":{"meta":{"requestId":"069cb400-a918-4493-9991-95d935fcc467","userId":null},"url":"/send-magic-link/","method":"POST","originalUrl":"/members/api/send-magic-link/","params":{},"headers":{"host":"localhost:2368","connection":"keep-alive","content-length":"623","pragma":"no-cache","cache-control":"no-cache","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36","sec-ch-ua":"\"Not(A:Brand\";v=\"99\", \"Google Chrome\";v=\"133\", \"Chromium\";v=\"133\"","content-type":"application/json","sec-ch-ua-mobile":"?0","accept":"*/*","origin":"http://localhost:2368","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:2368/lnd-v0-18-5-beta/","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en-GB,en;q=0.9,en-US;q=0.8,lt;q=0.7","cookie":"**REDACTED**"},"query":{}},"res":{"_headers":{"x-powered-by":"Express","cache-control":"no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0","access-control-allow-origin":"*","content-type":"application/json; charset=utf-8","content-length":"346","etag":"W/\"15a-h9bj081NPg6wPv5RhTMGmzNhfGM\"","vary":"Accept-Encoding"},"statusCode":500,"responseTime":"640ms"},"err":{"id":"5f295fd0-f3b2-11ef-8771-79c6a52f886d","domain":"http://localhost:2368/","code":"ESOCKET","name":"EmailError","statusCode":500,"level":"normal","message":"Failed to send email. Reason: self-signed certificate in certificate chain.","help":"\"Please see https://ghost.org/docs/config/#mail for instructions on configuring email.\"","stack":"Error: self-signed certificate in certificate chain\n    at createMailError (C:\\adapt\\ghost\\versions\\5.109.6\\core\\server\\services\\mail\\GhostMailer.js:81:12)\n    at TLSSocket.onConnectSecure (node:_tls_wrap:1677:34)\n    at TLSSocket.emit (node:events:519:28)\n    at TLSSocket._finishInit (node:_tls_wrap:1076:8)\n    at ssl.onhandshakedone (node:_tls_wrap:862:12)","hideStack":false},"msg":"Failed to send email. Reason: self-signed certificate in certificate chain.","time":"2025-02-25T19:54:49.807Z","v":0}

However if i take the link from the logs, I can login

(http://localhost:2368/members/?token=EFZZAwj-bVjSTKsGlFDMeVP7dXyT3B-i&action=signup&r=http%3A%2F%2Flocalhost%3A2368%2Flnd-v0-18-5-beta%2F\)

That sounds like it solves your immediate problem, anyway! :slight_smile:

I’ve used the settings above with good success, but not super recently. Certainly possible something has changed.