PHP程序调用msmtp时Office365账号发送邮件失败,报错'the server sent an invalid reply'(退出码EX_PROTOCOL)
这种同一个msmtp配置下一个账号正常、另一个出协议错误的情况确实挺挠头的,我给你几个实际排查的方向,你可以一步步试:
先确认账号基础信息是否正确
虽然你用XXXXXX代替了密码,但要仔细核对information账号的密码:有没有最近过期?有没有包含特殊字符(比如!@#$这类)在.msmtprc里没转义?另外,Office365如果开启了多重身份验证(MFA),普通密码是没法用的,得换成微软账号的「应用专用密码」才行,这个很容易忽略。检查TLS相关配置细节
Office365对SMTP的TLS版本有严格要求(至少TLS 1.2),你现在只写了tls_nocertcheck,可以试试补充这两个配置项:tls_starttls on tls_min_version tls1.2加到
information账号的配置块里,有时候默认的TLS协商版本不兼容就会触发协议错误。验证账号的SMTP发送权限
登录Office365的Exchange管理后台,检查information账号是否被管理员禁用了「SMTP客户端提交」权限;另外,有些企业版的Office365会限制非授权客户端的SMTP访问,需要确保账号在允许的列表里。绕过PHP,直接用命令行测试msmtp
先排除PHP层面的问题,直接在终端执行测试命令,能拿到更详细的错误日志:echo -e "Subject: Test Command Line Mail\n\nThis is a test from msmtp command line" | msmtp --account=information your-test-email@example.com执行后看输出的具体错误,比如是不是服务器返回了具体的权限提示,或者TLS握手失败的细节,这比PHP返回的泛泛的协议错误有用多了。
检查.msmtprc的格式问题
有时候配置文件里的小疏忽会导致大问题:比如每个配置项是不是单独占一行?有没有多余的空格?from地址和user地址是不是完全一致(包括大小写?虽然邮箱不区分,但有些服务器会严格校验)?再仔细核对一遍information块的每一行,有没有拼写错误(比如host是不是写错成smtp.office365.com了?你这里是对的,但再确认下)。
按这个顺序排查下来,应该能找到问题所在,大概率是密码、MFA或者TLS配置的锅。
备注:内容来源于stack exchange,提问作者George

