{"record":{"id":"ba3314e040385e3d","repo":"hcengineering/platform","slug":"both-smtp-and-ses-configuration-are-specified-ple","errorCode":null,"errorMessage":"Both SMTP and SES configuration are specified, please specify only one","messagePattern":"Both SMTP and SES configuration are specified, please specify only one","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"services/mail/pod-mail/src/config.ts","lineNumber":154,"sourceCode":"    Host: host as string,\n    Port: port,\n    Username: username,\n    Password: password,\n    TlsMode: tlsMode ?? TlsOptions.UPGRADE,\n    DebugLog: debugLog,\n    AllowSelfSigned: allowSelfSigned\n  }\n}\n\nconst config: Config = (() => {\n  const port = parseNumber(process.env[envMap.Port])\n  if (port === undefined) {\n    throw Error('Missing env variable: Port')\n  }\n  const isSmtpConfig = !isEmpty(process.env[envMap.SmtpHost])\n  const isSesConfig = !isEmpty(process.env[envMap.SesAccessKey])\n  if (isSmtpConfig && isSesConfig) {\n    throw Error('Both SMTP and SES configuration are specified, please specify only one')\n  }\n  if (!isSmtpConfig && !isSesConfig) {\n    throw Error('Please specify SES or SMTP configuration')\n  }\n  const params: Config = {\n    port,\n    source: process.env[envMap.Source],\n    replyTo: process.env[envMap.ReplyTo],\n    sesConfig: isSesConfig ? buildSesConfig() : undefined,\n    smtpConfig: isSmtpConfig ? buildSmtpConfig() : undefined\n  }\n\n  return params\n})()\n\nexport default config\n","sourceCodeStart":136,"sourceCodeEnd":171,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/mail/pod-mail/src/config.ts#L136-L171","documentation":"pod-mail supports exactly one delivery backend: SMTP or AWS SES, selected by the presence of SMTP_HOST / SES_ACCESS_KEY. If both are set, the config IIFE throws this error rather than guessing which backend to use.","triggerScenarios":"Environment contains both a non-empty SMTP_HOST and a non-empty SES_ACCESS_KEY when pod-mail starts.","commonSituations":"Merging old SMTP config with newly added SES variables in the same .env; a shared base env plus an override layer each contributing one backend; leftover variables from a backend migration.","solutions":["Decide on one backend and delete the other's variables: remove SES_ACCESS_KEY/SES_SECRET_KEY/SES_REGION to use SMTP, or remove SMTP_HOST (and SMTP_PORT etc.) to use SES.","Audit layered env files (base + override) so only one backend's variables survive.","Check for stale variables in k8s ConfigMaps/Secrets from previous deployments and strip them."],"exampleFix":"// before\nSMTP_HOST=smtp.example.com\nSMTP_PORT=587\nSES_ACCESS_KEY=AKIA...\nSES_SECRET_KEY=...\nSES_REGION=us-east-1\n// after\nSMTP_HOST=smtp.example.com\nSMTP_PORT=587","handlingStrategy":"validation","validationCode":"const smtp = !!process.env.SMTP_HOST;\nconst ses = !!process.env.SES_ACCESS_KEY;\nif (smtp && ses) {\n  throw new Error('Both SMTP and SES configured; remove one backend before starting');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await import('./config');\n} catch (err) {\n  if (err instanceof Error && err.message.includes('Both SMTP and SES')) {\n    console.error('Conflicting mail backends: keep only SMTP_HOST or only SES_ACCESS_KEY set');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Audit layered env files (base + overrides) so only one backend's variables survive.","After migrating backends, delete the old backend's variables rather than commenting them out in some layers only.","Add a deployment-time check asserting exactly one of SMTP_HOST / SES_ACCESS_KEY is set.","Clean stale keys from k8s ConfigMaps/Secrets when changing delivery backends."],"tags":["env","configuration","smtp","ses","conflict"],"backgroundTag":"conflicting-configuration","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}