hcengineering/platform · error · Error
Both SMTP and SES configuration are specified, please specif
Error message
Both SMTP and SES configuration are specified, please specify only one
What it means
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.
Source
Thrown at services/mail/pod-mail/src/config.ts:154
Host: host as string,
Port: port,
Username: username,
Password: password,
TlsMode: tlsMode ?? TlsOptions.UPGRADE,
DebugLog: debugLog,
AllowSelfSigned: allowSelfSigned
}
}
const config: Config = (() => {
const port = parseNumber(process.env[envMap.Port])
if (port === undefined) {
throw Error('Missing env variable: Port')
}
const isSmtpConfig = !isEmpty(process.env[envMap.SmtpHost])
const isSesConfig = !isEmpty(process.env[envMap.SesAccessKey])
if (isSmtpConfig && isSesConfig) {
throw Error('Both SMTP and SES configuration are specified, please specify only one')
}
if (!isSmtpConfig && !isSesConfig) {
throw Error('Please specify SES or SMTP configuration')
}
const params: Config = {
port,
source: process.env[envMap.Source],
replyTo: process.env[envMap.ReplyTo],
sesConfig: isSesConfig ? buildSesConfig() : undefined,
smtpConfig: isSmtpConfig ? buildSmtpConfig() : undefined
}
return params
})()
export default config
View on GitHub (pinned to 63e28dc964)
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.
Example fix
// before SMTP_HOST=smtp.example.com SMTP_PORT=587 SES_ACCESS_KEY=AKIA... SES_SECRET_KEY=... SES_REGION=us-east-1 // after SMTP_HOST=smtp.example.com SMTP_PORT=587
Defensive patterns
Strategy: validation
Validate before calling
const smtp = !!process.env.SMTP_HOST;
const ses = !!process.env.SES_ACCESS_KEY;
if (smtp && ses) {
throw new Error('Both SMTP and SES configured; remove one backend before starting');
} Try / catch
try {
await import('./config');
} catch (err) {
if (err instanceof Error && err.message.includes('Both SMTP and SES')) {
console.error('Conflicting mail backends: keep only SMTP_HOST or only SES_ACCESS_KEY set');
process.exit(1);
}
throw err;
} Prevention
- 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.
When it happens
Trigger: Environment contains both a non-empty SMTP_HOST and a non-empty SES_ACCESS_KEY when pod-mail starts.
Common situations: 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.
Related errors
- Please specify SES or SMTP configuration
- Invalid SMTP_TLS_MODE value. Must be one of: secure, upgrade
- Missing env variables for SES configuration: ${missingKeys.j
- Missing env variables for SMTP configuration: ${missingKeys.
- SMTP config is required for custom transporter
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/ba3314e040385e3d.
Report an issue: GitHub.