title: Spring Boot email sending throws SocketTimeoutException: Read timed out
body: <p>I've already researched the topic for a few days but none of the answers I found online did the trick for me.</p>
  
  <p>Context: I've got a Spring Boot web application which sends automatic emails notifications using Java Mail API and Spring Boot Starter Mail. </p>
  
  <p>It is using GMail SMTP server with a GSuite account. I recently upgraded to use Spring 5.0.6 and Spring Boot 2.0.2 and the email sending stopped working.</p>
  
  <p>A few clues:</p>
  
  <ul>
  <li>the Java code sending the email is the same as before</li>
  <li>Gmail SMTP still works correctly (from another VM using older version of the application with the same settings and authentication, the emails are sent properly).</li>
  <li>unless I am missing something, the application configuration remains the same as before</li>
  </ul>
  
  <p>The things that have changed:</p>
  
  <ul>
  <li>upgrade to Spring 5.0.6</li>
  <li>upgrade to Spring Boot 2.0.2</li>
  <li>changes in many places in the Java code to match this upgrades and add features in other parts of the app</li>
  <li>The IP address of the VM is different than before (AWS EC2 instance)</li>
  </ul>
  
  <p>Here are the relevant dependencies in pom.xml :</p>
  
  <pre><code>    &lt;!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;javax.mail&lt;/groupId&gt;
          &lt;artifactId&gt;javax.mail-api&lt;/artifactId&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-mail&lt;/artifactId&gt;
      &lt;/dependency&gt;
  </code></pre>
  
  <p>Here is the application.yml relevant to Spring mail:</p>
  
  <pre><code>spring:
    mail:
      host: ${FT_MAIL_SMTP_HOST}
       port: ${FT_MAIL_SMTP_PORT}
       username: ${FT_MAIL_SMTP_USERNAME}
       password: ${FT_MAIL_SMTP_PASSWORD}
       debug: false
       properties:
         mail:
           smtp:
             starttls:
               enable: ${FT_MAIL_SMTP_STARTTLS}
               required: ${FT_MAIL_SMTP_TLSREQUIRED}
             auth: ${FT_MAIL_SMTP_AUTH}
             connectiontimeout: ${FT_MAIL_SMTP_CONN_TIMEOUT}
             timeout: ${FT_MAIL_SMTP_TIMEOUT}
             writetimeout: ${FT_MAIL_SMTP_WRITE_TIMEOUT}
  </code></pre>
  
  <p>These variables are defined in the environment:</p>
  
  <pre><code>FT_MAIL_SMTP_HOST=smtp.gmail.com
  FT_MAIL_SMTP_PORT=587
  FT_MAIL_SMTP_USERNAME=myaccount@myapp.com
  FT_MAIL_SMTP_PASSWORD=mypassword
  
  FT_MAIL_SMTP_STARTTLS=true
  FT_MAIL_SMTP_TLSREQUIRED=true
  FT_MAIL_SMTP_AUTH=true
  FT_MAIL_SMTP_CONN_TIMEOUT=5000
  FT_MAIL_SMTP_TIMEOUT=5000
  FT_MAIL_SMTP_WRITE_TIMEOUT=5000
  </code></pre>
  
  <p>Here is the Spring @Service used to send the email (unchanged):</p>
  
  <pre><code>@Service
  public class EmailServiceImpl {
  
  @Autowired
  public JavaMailSender emailSender;
  
  @Autowired
  private SpringTemplateEngine templateEngine;
  
  @Value("${myapp.mail.from}")
  private String fromAddress;
  
  @Value("${myapp.mail.replyto}")
  private String replyToAddress;
  
  public void sendTemplatedMessage(String template, String to, String subject, Map&lt;String, Object&gt; model) throws MailException, MessagingException {  
      sendTemplatedMessage(template, to, fromAddress, replyToAddress, subject, model);
  }
  
  public void sendTemplatedMessage(String template, String to, String from, String subject, Map&lt;String, Object&gt; model) throws MailException, MessagingException { 
      sendTemplatedMessage(template, to, from, replyToAddress, subject, model);
  }
  
  private void sendTemplatedMessage(String template, String to, String from, String replyTo, String subject, Map&lt;String, Object&gt; model) throws MailException, MessagingException {    
  
      MimeMessage message = emailSender.createMimeMessage();
  
      MimeMessageHelper helper = new MimeMessageHelper(message,
              MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
              StandardCharsets.UTF_8.name());
  
      //helper.addAttachment("logo.png", new ClassPathResource("memorynotfound-logo.png"));
      Context context = new Context();
      context.setVariables(model);
      String html = templateEngine.process(template, context);
  
      helper.setTo(to);
      helper.setFrom(from);
      helper.setReplyTo(from);
      helper.setSubject(subject);
      helper.setText(html, true);
  
      emailSender.send(message);
  }
  
  public void sendSimpleMessage(String to, String from, String subject, String text) {
      try {           
          SimpleMailMessage message = new SimpleMailMessage(); 
          message.setTo(to);
          message.setFrom(from);
          message.setSubject(subject); 
          message.setText(text);
          emailSender.send(message);
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
  }
  </code></pre>
  
  <p>Now here is the error I get when trying to send an email:</p>
  
  <pre><code>04:42:19.900 [https-jsse-nio-443-exec-3] ERROR c.f.controller.StayController - Could not send Guest confirmation email to gfgorostidi@protonmail.com
  org.springframework.mail.MailSendException: Failed to close server connection after message sending; nested exception is javax.mail.MessagingException: Exception reading response;
    nested exception is:
   java.net.SocketTimeoutException: Read timed out
   at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:482)
   at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359)
   at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354)
   at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:61)
   at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:35)
   at com.myapp.controller.StayController.sendConfirmEmailToGuest(StayController.java:437)
   at com.myapp.controller.StayController.saveStay(StayController.java:383)
   at com.myapp.controller.StayController.createStay(StayController.java:163)
   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   ......
   ......
   ......
   at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
   at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
   at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
   at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
   at java.base/java.lang.Thread.run(Thread.java:844)
  Caused by: javax.mail.MessagingException: Exception reading response;
    nested exception is:
   java.net.SocketTimeoutException: Read timed out
   at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2202)
   at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1212)
   at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:473)
   ... 104 more
  Caused by: java.net.SocketTimeoutException: Read timed out
   at java.base/java.net.SocketInputStream.socketRead0(Native Method)
   at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
   at java.base/java.net.SocketInputStream.read(SocketInputStream.java:171)
   at java.base/java.net.SocketInputStream.read(SocketInputStream.java:141)
   at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:425)
   at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:65)
   at java.base/sun.security.ssl.SSLSocketImpl.bytesInCompletePacket(SSLSocketImpl.java:918)
   at java.base/sun.security.ssl.AppInputStream.read(AppInputStream.java:144)
   at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:124)
   at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
   at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:271)
   at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:89)
   at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2182)
   ... 106 more
  org.springframework.mail.MailSendException: Failed to close server connection after message sending; nested exception is javax.mail.MessagingException: Exception reading response;
    nested exception is:
   java.net.SocketTimeoutException: Read timed out
   at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:482)
   at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359)
   at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354)
   at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:61)
   at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:35)
   at com.myapp.controller.StayController.sendConfirmEmailToGuest(StayController.java:437)
   at com.myapp.controller.StayController.saveStay(StayController.java:383)
   at com.myapp.controller.StayController.createStay(StayController.java:163)
   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   ......
   ......
   ......
   at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
   at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
   at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
   at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
   at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
   at java.base/java.lang.Thread.run(Thread.java:844)
  Caused by: javax.mail.MessagingException: Exception reading response;
    nested exception is:
   java.net.SocketTimeoutException: Read timed out
   at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2202)
   at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1212)
   at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:473)
   ... 104 more
  Caused by: java.net.SocketTimeoutException: Read timed out
   at java.base/java.net.SocketInputStream.socketRead0(Native Method)
   at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
   at java.base/java.net.SocketInputStream.read(SocketInputStream.java:171)
   at java.base/java.net.SocketInputStream.read(SocketInputStream.java:141)
   at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:425)
   at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:65)
   at java.base/sun.security.ssl.SSLSocketImpl.bytesInCompletePacket(SSLSocketImpl.java:918)
   at java.base/sun.security.ssl.AppInputStream.read(AppInputStream.java:144)
   at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:124)
   at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
   at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:271)
   at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:89)
   at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2182)
   ... 106 more
  </code></pre>
  
  <p>I have tried setting an incorrect SMTP server or bad credentials and this made the connection fail, so I assumed the server and credentials are correct as they are, and the error happens after a successful connection.</p>
  
  <p>The account used hasn't reached its limit, as another VM uses the same credentials and sends emails without problem.</p>
  
  <p>I've tried changing "Start TLS" settings to false and use port 465 instead, but this isn't working either.</p>
  
  <p>Any help is appreciated !! Thanks in advance!</p>