通过AWS SES发送邮件遭退回并标记为垃圾邮件的问题排查
问题分析与解决方案
一、退信与垃圾邮件的因果关系
从你遇到的“持续被退回且标记为垃圾邮件”来看,大概率是邮件先被收件方反垃圾系统判定为垃圾,直接拒收退回,同时你的发件记录会被标记,进一步影响后续投递。如果是投递失败后被标记垃圾,通常是邮件已进入收件箱再被移到垃圾文件夹,不会触发退回动作。
二、DKIM未验证的影响
这是核心问题之一:
- AWS SES要求域名完成DKIM验证,才能让收件方系统有效确认发件身份。未完成验证时,邮件的可信度极低,会大幅增加被判定为垃圾邮件的概率,甚至直接被拒收。
- 虽然你验证了单个邮箱身份,但域名级别的DKIM缺失,收件方系统会认为发件域名身份不可靠,直接归类为高风险邮件。
三、代码问题分析
错误捕获逻辑完全无效
你的try-except只能捕获SES接口调用时的同步错误(比如权限不足、参数格式错),但如果SES已经接收请求,后续因垃圾邮件被收件方拒收的情况属于异步事件,不会在调用send_email时抛出异常,所以你的重试和错误捕获根本覆盖不了这类退信场景。邮件内容存在风险点
- 用f-string拼接的正文有大量多余缩进,格式混乱,会被反垃圾系统扣分;
- 正文里“Your account has been been locked out”有重复的“been”,语法错误也会增加垃圾判定风险。
重试逻辑不合理
如果是因为垃圾邮件被拒收,重试2次只会重复发送高风险邮件,不仅解决不了问题,还会进一步降低发件域名的信誉度。
四、修复建议
立即完成域名DKIM验证
登录AWS SES控制台,找到你的域名,按照指引添加DKIM记录到域名解析服务商(比如Route53),验证完成后邮件可信度会大幅提升。同时记得配置SPF记录,和DKIM配合使用。优化代码逻辑
- 修复邮件内容的格式和语法错误:
def email_reminder(user, subject_line, days_since_login, ses_client): if days_since_login >= 60: beginning_email_lines = f"""Hello {user}, We've noticed that you have not logged into your AWS account in {days_since_login} days. Your account has been locked out.""" else: beginning_email_lines = f"""Hello {user}, We've noticed that you have not logged into your AWS account in {days_since_login} days. Your account will be locked out in {60 - days_since_login} day(s).""" - 调整错误捕获逻辑,仅处理SES同步调用错误,投递失败通过SNS订阅SES退信通知来监控:
def email_reminder(user, subject_line, days_since_login, ses_client): # 修复后的邮件内容 if days_since_login >= 60: beginning_email_lines = f"""Hello {user}, We've noticed that you have not logged into your AWS account in {days_since_login} days. Your account has been locked out.""" else: beginning_email_lines = f"""Hello {user}, We've noticed that you have not logged into your AWS account in {days_since_login} days. Your account will be locked out in {60 - days_since_login} day(s).""" try: ses_client.send_email( Source='admin@ourdomain.com', Destination={'ToAddresses': [user]}, Message={ 'Subject': {'Data': subject_line}, 'Body': {'Text': {'Data': beginning_email_lines}} } ) logger.info(f"邮件已成功发送给 {user}") except Exception as e: logger.error(f"发送邮件给 {user} 失败: {str(e)}") raise - 移除无效的重试逻辑,避免重复发送高风险邮件。
- 修复邮件内容的格式和语法错误:
提升发件信誉
- 避免多次向同一个邮箱发送测试邮件,触发反垃圾阈值;
- 检查收件邮箱是否存在拼写错误,部分退信可能是因为邮箱不存在。
内容的提问来源于stack exchange,提问作者tantan69
相关产品推荐
相关产品推荐

