{"record":{"id":"52ff95412f22ec2d","repo":"usememos/memos","slug":"notification-email-cannot-enable-both-usetls-and-u","errorCode":null,"errorMessage":"notification email cannot enable both useTls and useSsl","messagePattern":"notification email cannot enable both useTls and useSsl","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"store/deployment_config.go","lineNumber":280,"sourceCode":"\t\t\t\t\treturn errors.Errorf(\"storageSetting default S3 config.%s is required\", field.name)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tcase storepb.InstanceSettingKey_MEMO_RELATED:\n\t\tif setting.GetMemoRelatedSetting() == nil {\n\t\t\treturn errors.New(\"memoRelatedSetting must be populated for key MEMO_RELATED\")\n\t\t}\n\tcase storepb.InstanceSettingKey_NOTIFICATION:\n\t\tnotification := setting.GetNotificationSetting()\n\t\tif notification == nil {\n\t\t\treturn errors.New(\"notificationSetting must be populated for key NOTIFICATION\")\n\t\t}\n\t\tif email := notification.Email; email != nil && email.Enabled {\n\t\t\tif strings.TrimSpace(email.SmtpHost) == \"\" || email.SmtpPort <= 0 || strings.TrimSpace(email.FromEmail) == \"\" {\n\t\t\t\treturn errors.New(\"enabled notification email requires smtpHost, a positive smtpPort, and fromEmail\")\n\t\t\t}\n\t\t\tif email.UseTls && email.UseSsl {\n\t\t\t\treturn errors.New(\"notification email cannot enable both useTls and useSsl\")\n\t\t\t}\n\t\t}\n\tcase storepb.InstanceSettingKey_AI:\n\t\tif setting.GetAiSetting() == nil {\n\t\t\treturn errors.New(\"aiSetting must be populated for key AI\")\n\t\t}\n\t\tif err := normalizeDeploymentAISetting(setting.GetAiSetting()); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase storepb.InstanceSettingKey_BASIC, storepb.InstanceSettingKey_TAGS:\n\t\treturn errors.Errorf(\"key %s cannot be deployment configured\", setting.Key)\n\tdefault:\n\t\treturn errors.Errorf(\"unsupported instance setting key %s\", setting.Key)\n\t}\n\treturn nil\n}\n\nfunc normalizeDeploymentAISetting(setting *storepb.InstanceAISetting) error {","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/usememos/memos/blob/14d757ce1fb31c78590f374bc042f8dbedbc20d7/store/deployment_config.go#L262-L298","documentation":"Thrown when an enabled notification email config sets both useTls and useSsl to true. These select mutually exclusive transport security modes: useTls means STARTTLS on the plain port, useSsl means implicit TLS (SMTPS, typically port 465). Enabling both is ambiguous, so the deployment validator rejects the file at startup instead of guessing.","triggerScenarios":"\"email\": { \"enabled\": true, \"useTls\": true, \"useSsl\": true, ... } — often from copy-pasting two example configs or setting every boolean in the block to true.","commonSituations":"Operators flipping all security flags on assuming 'more TLS is safer'; port confusion (587 wants useTls, 465 wants useSsl).","solutions":["Pick one mode: port 587/25 with \"useTls\": true, \"useSsl\": false; or port 465 with \"useSsl\": true, \"useTls\": false.","Match the mode to the port your SMTP provider documents."],"exampleFix":"// before\n{ \"enabled\": true, \"smtpPort\": 465, \"useTls\": true, \"useSsl\": true, ... }\n\n// after\n{ \"enabled\": true, \"smtpPort\": 465, \"useTls\": false, \"useSsl\": true, ... }","handlingStrategy":"validation","validationCode":"if e.UseTls && e.UseSsl {\n    return errors.New(\"email cannot set both useTls and useSsl\")\n}","typeGuard":"func tlsModeIsUnambiguous(e *storepb.EmailSetting) bool { return !(e.GetUseTls() && e.GetUseSsl()) }","tryCatchPattern":null,"preventionTips":["Map port to mode in templates: 587 -> useTls, 465 -> useSsl.","Never default both booleans to true 'for safety'."],"tags":["configuration","validation","notification","email","smtp","tls","startup"],"backgroundTag":null,"analyzedSha":"14d757ce1fb31c78590f374bc042f8dbedbc20d7","analyzedAt":"2026-08-15T09:27:36.538Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}