title: Grails 3 mail: Must issue a STARTTLS command first
body: <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>