{"record":{"id":"32eb11b32a2358a5","repo":"louislam/uptime-kuma","slug":"smtp-connection-doesn-t-verify-e","errorCode":null,"errorMessage":"SMTP connection doesn't verify: ${e}","messagePattern":"SMTP connection doesn't verify: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/monitor-types/smtp.js","lineNumber":26,"sourceCode":"    /**\n     * @inheritdoc\n     */\n    async check(monitor, heartbeat, _server) {\n        let options = {\n            port: monitor.port || 25,\n            host: monitor.hostname,\n            secure: monitor.smtpSecurity === \"secure\", // use SMTPS (not STARTTLS)\n            ignoreTLS: monitor.smtpSecurity === \"nostarttls\", // don't use STARTTLS even if it's available\n            requireTLS: monitor.smtpSecurity === \"starttls\", // use STARTTLS or fail\n        };\n        let transporter = nodemailer.createTransport(options);\n        try {\n            await transporter.verify();\n\n            heartbeat.status = UP;\n            heartbeat.msg = \"SMTP connection verifies successfully\";\n        } catch (e) {\n            throw new Error(`SMTP connection doesn't verify: ${e}`);\n        } finally {\n            transporter.close();\n        }\n    }\n}\n\nmodule.exports = {\n    SMTPMonitorType,\n};\n","sourceCodeStart":8,"sourceCodeEnd":36,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/monitor-types/smtp.js#L8-L36","documentation":"The SMTP monitor builds a nodemailer transport from monitor.hostname, port, and smtpSecurity mode, then calls transporter.verify() to open and authenticate a connection. Any failure (socket, TLS, auth) is caught and re-thrown as 'SMTP connection doesn\\'t verify: <e>'. The original nodemailer error is interpolated, so the message after the colon carries the real cause.","triggerScenarios":"transporter.verify() rejects: host unreachable, connection refused, TLS handshake failure, STARTTLS required but unavailable, or authentication error. The finally block still calls transporter.close().","commonSituations":"Wrong port (25/465/587 mismatch with smtpSecurity), secure vs STARTTLS mismatch, firewall blocking outbound SMTP, credentials wrong, or host doing opportunistic TLS that fails.","solutions":["Match the port to smtpSecurity: 465 for 'secure' (SMTPS), 587 for 'starttls', 25 for plain/'nostarttls'.","Confirm outbound connectivity from the Uptime Kuma host: openssl s_client -connect host:465 or telnet host 587.","Verify credentials and that the user is permitted to relay/auth.","If STARTTLS is required, ensure the server advertises it and the cert is valid."],"exampleFix":"// before\nmonitor.smtpSecurity = 'secure';   // but port 587\n// after\nmonitor.smtpSecurity = 'starttls';  // matches port 587","handlingStrategy":"try-catch","validationCode":"const net = require('net');\nfunction preflightSmtp(host, port, security) {\n  // sanity: port matches declared security mode\n  const ok = (security === 'secure' && port === 465) ||\n             (security === 'starttls' && port === 587) ||\n             (security === 'nostarttls' && port === 25);\n  if (!ok) console.warn(`Port ${port} may not match SMTP security mode '${security}'`);\n}","typeGuard":"function isSmtpPortModeMatch(port, security) {\n  return (security === 'secure' && port === 465) ||\n         (security === 'starttls' && port === 587) ||\n         (security === 'nostarttls' && port === 25);\n}","tryCatchPattern":"try {\n  await smtpMonitor.check(monitor, heartbeat, server);\n} catch (e) {\n  if (/doesn't verify/.test(e.message)) {\n    // inner cause is after the colon: GREETING/EAUTH/ECONNECTION/EENVELOPE\n    heartbeat.status = DOWN;\n    heartbeat.msg = e.message;\n  }\n}","preventionTips":["Match port to security mode (465/SMTPS, 587/STARTTLS, 25/plain).","Verify outbound 25/465/587 are not blocked by the hoster.","Use valid credentials and confirm the user is permitted to authenticate."],"tags":["smtp","nodemailer","email","tls","network"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}