You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

代码触发STARTTLS错误,已导入相关Jar包仍未解决,求排查方案

解决STARTTLS要求但主机不支持的邮件发送问题

看你遇到的javax.mail.MessagingException: STARTTLS is required but host does not support STARTTLS错误,结合你的代码配置,问题核心出在端口选择和STARTTLS配置的冲突上,咱们一步步调整就能解决:

问题根源分析

你当前的配置同时做了两件矛盾的事:

  • 配置了mail.smtp.socketFactory.class用SSL直接连接,还指定了465端口(这是SMTP over SSL的标准端口,连接建立时就已经是加密状态,不需要再通过STARTTLS升级连接)
  • 又强制开启了mail.smtp.starttls.enable=true和mail.smtp.starttls.required=true,要求必须使用STARTTLS,但你的邮件服务器在465端口上根本不支持这个流程(因为没必要),所以触发了冲突报错

两种可行解决方案

方案一:用SMTP over SSL(465端口),关闭STARTTLS强制要求

如果你的邮件服务器支持465端口的SSL连接,直接调整配置,去掉STARTTLS相关的强制规则:

boolean sessionDebug=false; 
Properties props=System.getProperties(); 
// 保留SSL Socket Factory配置,适配465端口的加密连接
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
props.put("mail.smtp.host", host); 
props.put("mail.smtp.port", "465"); 
props.put("mail.smtp.auth", "true"); 
// 去掉STARTTLS相关配置,因为465端口不需要
// props.put("mail.smtp.starttls.enable", "true"); 
// props.put("mail.smtp.starttls.required", "true"); 
final javax.mail.Session mailSession = javax.mail.Session.getInstance(props); 
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); 
props.put("mail.smtp.debug", "true"); 
mailSession.setDebug(sessionDebug); 

Message msg = new MimeMessage(mailSession); 
msg.setFrom(new InternetAddress(from)); 
InternetAddress[] address={new InternetAddress(to)}; 
msg.setRecipients(Message.RecipientType.TO,address); 
msg.setSubject(subject); 
msg.setSentDate(new Date()); 
msg.setText(msgText); 

Transport transport =mailSession.getTransport("smtp"); 
System.out.println("smtp"); 
transport.connect(host,user,pass); 
System.out.println("smtp connection"); 
transport.sendMessage(msg,msg.getAllRecipients()); 
System.out.println("smtp message"); 
transport.close();

方案二:用STARTTLS(587端口),去掉SSL Socket Factory配置

如果你的邮件服务器支持587端口的STARTTLS流程,就切换到这个标准端口,适配STARTTLS的配置逻辑:

boolean sessionDebug=false; 
Properties props=System.getProperties(); 
// 去掉SSL Socket Factory,因为STARTTLS是先建立明文连接再升级为加密状态
// props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
props.put("mail.smtp.starttls.enable", "true"); 
props.put("mail.smtp.host", host); 
// 改用STARTTLS的标准端口587
props.put("mail.smtp.port", "587"); 
props.put("mail.smtp.auth", "true"); 
props.put("mail.smtp.starttls.required", "true"); 
final javax.mail.Session mailSession = javax.mail.Session.getInstance(props); 
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); 
props.put("mail.smtp.debug", "true"); 
mailSession.setDebug(sessionDebug); 

Message msg = new MimeMessage(mailSession); 
msg.setFrom(new InternetAddress(from)); 
InternetAddress[] address={new InternetAddress(to)}; 
msg.setRecipients(Message.RecipientType.TO,address); 
msg.setSubject(subject); 
msg.setSentDate(new Date()); 
msg.setText(msgText); 

Transport transport =mailSession.getTransport("smtp"); 
System.out.println("smtp"); 
transport.connect(host,user,pass); 
System.out.println("smtp connection"); 
transport.sendMessage(msg,msg.getAllRecipients()); 
System.out.println("smtp message"); 
transport.close();

额外排查建议

  • 先确认你的邮件服务器支持哪种加密方式:可以用openssl s_client -connect 你的主机:465测试465端口的SSL连接;或者用telnet 你的主机:587后输入EHLO localhost,看返回内容里有没有STARTTLS字样,以此判断是否支持该流程
  • 开启mail.smtp.debug=true,能看到详细的邮件服务器交互日志,方便进一步定位问题

内容的提问来源于stack exchange,提问作者Hanin Qaddoura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:47:03