{"record":{"id":"7e22376730343de8","repo":"immich-app/immich","slug":"failed-to-verify-smtp-configuration-7e2237","errorCode":null,"errorMessage":"Failed to verify SMTP configuration","messagePattern":"Failed to verify SMTP configuration","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/notification.service.ts","lineNumber":268,"sourceCode":"    this.websocketRepository.clientSend('on_notification', userId, mapNotification(item));\n  }\n\n  @OnEvent({ name: 'SessionDelete' })\n  onSessionDelete({ sessionId }: ArgOf<'SessionDelete'>) {\n    // after the response is sent\n    setTimeout(() => this.websocketRepository.clientSend('on_session_delete', sessionId, sessionId), 500);\n  }\n\n  async sendTestEmail(id: string, dto: SystemConfigSmtpDto, tempTemplate?: string) {\n    const user = await this.userRepository.get(id, { withDeleted: false });\n    if (!user) {\n      throw new Error('User not found');\n    }\n\n    try {\n      await this.emailRepository.verifySmtp(dto.transport);\n    } catch (error) {\n      throw new BadRequestException('Failed to verify SMTP configuration', { cause: error });\n    }\n\n    const { server } = await this.getConfig({ withCache: false });\n    const { html, text } = await this.emailRepository.renderEmail({\n      template: EmailTemplate.TEST_EMAIL,\n      data: {\n        baseUrl: getExternalDomain(server),\n        displayName: user.name,\n      },\n      customTemplate: tempTemplate!,\n    });\n    const { messageId } = await this.emailRepository.sendEmail({\n      to: user.email,\n      subject: 'Test email from Immich',\n      html,\n      text,\n      from: dto.from,\n      replyTo: dto.replyTo || dto.from,","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/notification.service.ts#L250-L286","documentation":"sendTestEmail validates the SMTP transport by attempting a live verification (verifySmtp) before rendering and sending a test email. If the repository's SMTP check fails for any reason (bad host, port, credentials, TLS), the original error is wrapped in a BadRequestException with this message. It signals the stored/system email config cannot be used to send mail.","triggerScenarios":"Calling POST /api/notifications/test-email (sendTestEmail) with a TestEmailDto whose transport (smtp host/port/username/password/secure settings) fails the verifySmtp check — connection refused, auth failure, or TLS handshake error.","commonSituations":"Wrong SMTP host or port (465 vs 587 mismatch with secure flag), incorrect username/password, self-signed certificates rejected by TLS, firewall blocking outbound SMTP, Gmail requiring app passwords.","solutions":["Verify SMTP host, port, username, and password in the notification settings; ensure the secure flag matches the port (465=secure, 587=starttls).","Test connectivity from the server host (e.g. `nc -vz smtp.example.com 587`) to rule out firewall/DNS issues.","If using Gmail or Office365, use an app password / SMTP AUTH with less-secure-app or OAuth settings.","Inspect the `cause` of the BadRequestException in server logs for the underlying SMTP error detail."],"exampleFix":"// before\nawait this.emailRepository.verifySmtp({ host: 'smtp.gmail.com', port: 587, secure: true });\n// after\nawait this.emailRepository.verifySmtp({ host: 'smtp.gmail.com', port: 587, secure: false }); // 587 uses STARTTLS, not implicit TLS","handlingStrategy":"try-catch","validationCode":"// pre-check config before calling\nconst ok = smtpHost && smtpPort > 0 && smtpPort < 65536 && (smtpUsername ? smtpPassword !== undefined : true);\nif (!ok) throw new Error('Incomplete SMTP settings');","typeGuard":null,"tryCatchPattern":"try {\n  await api.notificationsApi.sendTestEmail({ transport });\n} catch (e) {\n  if (e.status === 400 && String(e.message).includes('Failed to verify SMTP configuration')) {\n    // surface e.cause / check host, port, credentials, TLS\n  } else throw e;\n}","preventionTips":["Match the secure flag to the port (465 implicit TLS, 587 STARTTLS).","Test SMTP credentials with a standalone client (swaks, msmtp) before wiring them in.","Allowlist outbound SMTP ports on the server firewall.","Use app passwords for providers like Gmail instead of the account password."],"tags":["email","smtp","configuration","bad-request"],"backgroundTag":"invalid-config-value","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}