Javamail Could not convert socket to TLS GMail
JavaEmailSslSmtpGmailJava Problem Overview
I'm trying to send an email using JavaMail through Gmail SMTP Server. This is the code:
final String username = "[email protected]";
final String password = "mygmailpassword";
Properties props = new Properties();
props.put("mail.smtp.auth", true);
props.put("mail.smtp.starttls.enable", true);
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}
);
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("[email protected]"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("[email protected]"));
message.setSubject("Testing Subject");
message.setText("Dear Mail Crawler," + "\n\n No spam to my email, please!");
Transport.send(message);
System.out.println("Done");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
Returns an this error:
> Could not convert socket to TLS;
The complete stacktrace:
> Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Could not convert socket to TLS; nested exception is: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at Test.main(Test.java:43) Caused by: javax.mail.MessagingException: Could not convert socket to TLS; nested exception is: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1907) at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:666) at javax.mail.Service.connect(Service.java:317) at javax.mail.Service.connect(Service.java:176) at javax.mail.Service.connect(Service.java:125) at javax.mail.Transport.send0(Transport.java:194) at javax.mail.Transport.send(Transport.java:124) at Test.main(Test.java:38) Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149) at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:549) at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:486) at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:1902) ... 7 more Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217) at sun.security.validator.Validator.validate(Validator.java:218) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185) ... 17 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318) ... 23 more
Java Solutions
Solution 1 - Java
props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
Solution 2 - Java
I disabled avast antivirus for 10 minutes and get it working.
Solution 3 - Java
Make sure your antivirus program isn't interfering and be sure to add an exclusion to your firewall.
Solution 4 - Java
I got similar problem when default SSL protocol for sending emails was set to TLSv1 and smtp server was not supporting this protocol anymore. Trick was to use newer protocol:
mail.smtp.ssl.protocols=TLSv1.2
Solution 5 - Java
The first answer from @carlos worked for me:
session.getProperties().put("mail.smtp.ssl.trust", "smtp.gmail.com");
I have tested the property below and worked perfectly for me too:
session.getProperties().put("mail.smtp.starttls.enable", "true");
The two properties alone solved this type of problem, but by guarantee I used both.
Solution 6 - Java
In my case the problem was solved by deleting the line
prop.put("mail.smtp.starttls.enable", "true");
It may be because of some ssl configuration errors on email server, I'm not sure. Email server administrators never admit it and always blame hosting provider :)
Solution 7 - Java
After a full day of search, I disabled Avast for 10 minutes and Windows Firewall (important) and everything started working!
This was my error:
Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS; nested exception is: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS; nested exception is: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Here is how to fix the issue in Avast 19.8.2393 by adding an exclusion to SMTP port 587 (or whichever port your application uses):
-
Open Avast
-
Click on 'Settings'
-
Click on 'Troubleshooting' and then 'Open old settings'
- Click again on 'Troubleshooting', scroll down to 'Redirect settings' and delete the port that your app uses.
In my case, I just removed 587 from SMTP ports.
Now I am able to use Avast and also have my Windows Firewall switched on (no need to add additional exclusion for the Firewall).
Here are my application.properties e-mail properties:
###### I am using a Google App Password which I generated in my Gmail Security settings ######
spring.mail.host = smtp.gmail.com
spring.mail.port = 587
spring.mail.protocol = smtp
spring.mail.username = gmail account
spring.mail.password = password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
Solution 8 - Java
above application.properties worked amazing for me:
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
Solution 9 - Java
This can also be if the application does not support the TLS version the SMTP host is using.
For example, trying to configure an SMTP server that uses TLSv1.2 without fallback, when your application(or java program using an older javax.mail JAR) supports only upto TLSv1.1.
Solution 10 - Java
Try changing the port to 465
mail.smtp.socketFactory.port=465
mail.smtp.port=465
Solution 11 - Java
If your context is android application , then make sure your android device time is set to current date and time. The underlying exception is "The SSL certificates was not getting authenticated."
Solution 12 - Java
Yes, it works for me on localhost:
props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
The error is only thrown on localhost, so you should try on remote servers too. Usually, it is the snippet of code mentioned above that works well without ssl.trust
property
Solution 13 - Java
It depends on the "Nested Exception". If the nested exception is "no appropriate protocol" then specify the protocol in a System property:
-Dmail.smtp.ssl.protocols=TLSv1.2
I see that some people suggest to set it in the code that creates the STMP session, but that would require a patching and deployment if you want to update the value in the future. Using a System property allows you to update it without changing the code.
Solution 14 - Java
Here is the working solution bro. It's guaranteed
-
First of all open your gmail account from which you wanted to send mail, like in you case ""[email protected]"
-
open this link below https://support.google.com/accounts/answer/6010255?hl=en
-
click on "Go to the "Less secure apps" section in My Account." option
-
Then turn on it
-
that's it (:
here is my code
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
public class SendEmail {
final String senderEmailID = "Sender Email id";
final String senderPassword = "Sender Pass word";
final String emailSMTPserver = "smtp.gmail.com";
final String emailServerPort = "465";
String receiverEmailID = null;
static String emailSubject = "Test Mail";
static String emailBody = ":)";
public SendEmail(String receiverEmailID, String emailSubject, String emailBody)
{
this.receiverEmailID=receiverEmailID;
this.emailSubject=emailSubject;
this.emailBody=emailBody;
Properties props = new Properties();
props.put("mail.smtp.user",senderEmailID);
props.put("mail.smtp.host", emailSMTPserver);
props.put("mail.smtp.port", emailServerPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", emailServerPort);
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
SecurityManager security = System.getSecurityManager();
try
{
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(props, auth);
MimeMessage msg = new MimeMessage(session);
msg.setText(emailBody);
msg.setSubject(emailSubject);
msg.setFrom(new InternetAddress(senderEmailID));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress(receiverEmailID));
Transport.send(msg);
System.out.println("Message send Successfully:)");
}
catch (Exception mex)
{
mex.printStackTrace();
}
}
public class SMTPAuthenticator extends javax.mail.Authenticator
{
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(senderEmailID, senderPassword);
}
}
public static void main(String[] args) {
SendEmail mailSender;
mailSender = new SendEmail("Receiver Email id","Testing Code 2 example","Testing Code Body yess");
}
}
Solution 15 - Java
Check the version of your JavaMail lib (mail.jar or javax.mail.jar). Maybe you need a newer one. Download the newest version from here: https://javaee.github.io/javamail/
Solution 16 - Java
Below set of properties in application.properties
did the trick for me:
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=<gmail_id>
spring.mail.password=<gmail_password>
spring.mail.properties.mail.smtp.ssl.trust=smtp.gmail.com
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
Note that if you have enabled 2-Step Verification for your Gmail account then the gmail_password
in the above configuration should not be an ordinary password but a 16-character application password generated for your Google account. Follow this link to see the details and to generate your Google App Password.
Solution 17 - Java
In my case, I was using OpenJDK, when I switched to OracleJDK the issue was resolved.
Solution 18 - Java
Try using the smtpsend program that comes with JavaMail, as described here. If that fails in the same way, there's something wrong with your JDK configuration or your network configuration.
Solution 19 - Java
What helped me fix this, and i have tried everything before this, was to configure my installed jre to JRE 1.8.
Steps in Eclipse: Windows>preferences>java>installed JRE>jre1.8.0
If it is set to jdk, switch to jre(which is what is supposed to be set to by default with the latest java version).