62
votes

I am trying to send an email using JavaMail through gmails SMTP Server. however this 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
16
please give the complete stack trace. Your exact code runs fine on my machineLaabidi Raissi
@Laabidi I already posted it.user962206

16 Answers

140
votes
props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
33
votes

I disabled avast antivirus for 10 minutes and get it working.

32
votes

Make sure your antivirus program isn't interfering and be sure to add an exclusion to your firewall.

12
votes

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

11
votes

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.

6
votes

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 :)

6
votes

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):

  1. Open Avast

  2. Click on 'Settings'

  3. Click on 'Troubleshooting' and then 'Open old settings'

enter image description here

  1. Click again on 'Troubleshooting', scroll down to 'Redirect settings' and delete the port that your app uses.

enter image description here

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
3
votes

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
2
votes

Try changing the port to 465

mail.smtp.socketFactory.port=465
mail.smtp.port=465
2
votes

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.

1
votes

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."

1
votes

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

0
votes

Here is the working solution bro. It's guaranteed

1) First of all open your gmail account from which you wanted to send mail, like in you case ""[email protected]"

2) open this link below https://support.google.com/accounts/answer/6010255?hl=en

3) click on "Go to the "Less secure apps" section in My Account." option

4) Then turn on it

5) 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");
    }

}
0
votes

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/

-1
votes

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.

-1
votes

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).