Grails 3 mail: Must issue a STARTTLS command first
<p>I know this question has been asked many times in many different places, but for some reason, I can't seem to get it to work. I realize what the issue is, I just can't seem to figure out the yaml syntax or something simple like that.</p>

<p>I'm using Grails 3 with the "mail" plugin (2.0.0.RC6).</p>

<p>Here is a snippet of my application.yml:</p>

<pre><code>grails:
    serverURL: &lt;url&gt;
    mail:
        host: &lt;host&gt;
        port: 587
        username: &lt;username&gt;
        password: &lt;password&gt;
        props:
            ? "mail.smtp.auth" : true
            ? "mail.smtp.starttls.enable" : true
            ? "mail.smtp.starttls.required" : true
            ? "mail.smtp.socketFactory.class" : "javax.net.ssl.SSLSocketFactory"
            ? "mail.smtp.socketFactory.fallback" : false
            ? "mail.smtp.port" : 587
</code></pre>

<p>I've tried many combinations of quotes with no luck. The <code>?</code> instead of a <code>-</code> indicates a map, which is what I want I think.</p>

<p>Here is the specific error message if it helps:</p>

<pre><code>Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first
. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.mail.MailSendException: Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first

        at grails.plugins.mail.MailMessageBuilder.sendMessage(MailMessageBuilder.groovy:130)
        at grails.plugins.mail.MailService.sendMail(MailService.groovy:53)
        at grails.plugins.mail.MailService.sendMail(MailService.groovy:57)
        at website.UserController.register(UserController.groovy:60)
        ... 3 common frames omitted
</code></pre>

<p>This is a custom mail server running Postfix (first time setting it up). I am able to connect to it and send mail with Thunderbird. Thunderbird is using STARTTLS and port 587 to connect. As far as I know, I haven't been able to do just SSL/TLS.</p>

<p><strong>update:</strong></p>

<p>I've removed the factory config and fixed the yaml map stuff. Now I'm getting another error.</p>

<pre><code>grails:
    serverURL: https://test.neonorb.com
    mail:
        host: test.neonorb.com
        port: 587
        username: neonorb
        password: pass
        props:
            mail.smtp.starttls.enable: true
            mail.smtp.port: 587
</code></pre>

<p>Here is the exception:</p>

<pre><code>unable to find valid certification path to requested target. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.mail.MailSendException: 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
        at grails.plugins.mail.MailMessageBuilder.sendMessage(MailMessageBuilder.groovy:130)
        at grails.plugins.mail.MailService.sendMail(MailService.groovy:53)
        at grails.plugins.mail.MailService.sendMail(MailService.groovy:57)
        at website.UserController.register(UserController.groovy:60)
        ... 3 common frames omitted
Caused by: javax.mail.MessagingException: Could not convert socket to TLS
        at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2046)
        at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:711)
        at javax.mail.Service.connect(Service.java:366)
        ... 7 common frames omitted
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.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:598)
        at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:525)
        at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2041)
        ... 9 common frames omitted
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        ... 12 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        ... 12 common frames omitted
</code></pre>

<p>According to Google, this is because the certificate is self-signed, and Java doesn't trust it. My certificate is not self-signed, and is made from Let's Encrypt.</p>