title: com.sun.mail.util.MailConnectException: Couldn't connect to host. It works on staging but not on prod in Azure
body: <p>Im dealing with a problem when trying to send recover password emails from my app. It works just fine in staging, but not in prod. I've checked and all data is the same, so I really don't understand what im missing.</p>
  <pre><code>    private Properties createProperties(String host) {
      final Properties properties = System.getProperties();
  
      // Setup mail server
      properties.put(&quot;mail.smtp.host&quot;, host);
      properties.put(&quot;mail.smtp.port&quot;, &quot;587&quot;);
      properties.put(&quot;mail.smtp.auth&quot;, &quot;true&quot;);
      properties.put(&quot;mail.smtp.starttls.enable&quot;, &quot;true&quot;);
      properties.put(&quot;mail.debug&quot;, &quot;true&quot;);
      properties.put(&quot;mail.smtp.localhost&quot;, ipAddress);
      return properties;
  }
  
  
      public boolean sendHtml(String recipient, String subject, String html) {
      logger.debug(&quot;[ PASSWORD ] attempting to send email&quot;);
      try {
          final MimeMessage message = new MimeMessage(session);
          message.addHeader(&quot;Content-type&quot;, &quot;text/HTML; charset=UTF-8&quot;);
          message.addHeader(&quot;format&quot;, &quot;flowed&quot;);
          message.addHeader(&quot;Content-Transfer-Encoding&quot;, &quot;8bit&quot;);
          message.setSentDate(new Date());
  
          message.setFrom(new InternetAddress(sender, senderName));
          message.addRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient, false));
          message.setSubject(subject, &quot;UTF-8&quot;);
          message.setContent(html, &quot;text/html&quot;);
  
          logger.debug(&quot;[INFO] [RECOVER PASSWORD] Sending email to recipient &quot; + recipient + &quot; from &quot; + sender);
          Transport.send(message);
          logger.debug(&quot;[INFO] [RECOVER PASSWORD] Email sent successfully to recipient &quot; + recipient + &quot; from &quot; + sender);
          return true;
      } catch (Exception e) {
          logger.debug(&quot;[ PASSWORD ] FAILED &quot;);
          logger.debug(e.getMessage());
          logger.debug(e.toString());
          e.printStackTrace();
          return false;
      }
  }
  </code></pre>
  <p>The host im using: smtp-relay.gmail.com</p>
  <p>The error im getting:</p>
  <pre><code>2022-08-31 13:46:44 [http-nio-8080-exec-4] DEBUG c.m.pay.business.email.EmailSender - [ PASSWORD ] FAILED 
  2022-08-31 13:46:44 [http-nio-8080-exec-4] DEBUG c.m.pay.business.email.EmailSender - Couldn't connect to host, port: smtp-relay.gmail.com, 587; timeout -1
  2022-08-31 13:46:44 [http-nio-8080-exec-4] DEBUG c.m.pay.business.email.EmailSender - com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp-relay.gmail.com, 587; timeout -1;
    nested exception is:
      java.net.ConnectException: Operation timed out (Connection timed out)
  com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp-relay.gmail.com, 587; timeout -1;
    nested exception is:
      java.net.ConnectException: Operation timed out (Connection timed out)
      at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2209)
      at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
      at javax.mail.Service.connect(Service.java:388)
      at javax.mail.Service.connect(Service.java:246)
      at javax.mail.Service.connect(Service.java:195)
      at javax.mail.Transport.send0(Transport.java:254)
      at javax.mail.Transport.send(Transport.java:124)
      at com.metro.pay.business.email.EmailSender.sendHtml(EmailSender.java:48)
      at com.metro.pay.presentation.controller.SubscriberController.startRecoverPasswordProcess(SubscriberController.java:416)
      at com.metro.SwaggerCodegen.api.SubscriberApi._startRecoverPasswordProcess(SubscriberApi.java:737)
      at com.metro.SwaggerCodegen.api.SubscriberApi$$FastClassBySpringCGLIB$$378e29ab.invoke(&lt;generated&gt;)
      at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
      at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
      at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
      at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
      at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
      at com.metro.pay.presentation.controller.SubscriberController$$EnhancerBySpringCGLIB$$824e8ec9._startRecoverPasswordProcess(&lt;generated&gt;)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
      at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
      at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060)
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
      at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:113)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
      at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
      at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
      at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
      at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at com.metro.pay.business.security.web.JwtRequestFilter.doFilterInternal(JwtRequestFilter.java:79)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
      at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
      at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
      at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
      at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
      at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
      at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:764)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:748)
  Caused by: java.net.ConnectException: Operation timed out (Connection timed out)
      at java.net.PlainSocketImpl.socketConnect(Native Method)
      at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
      at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
      at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
      at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
      at java.net.Socket.connect(Socket.java:589)
      at java.net.Socket.connect(Socket.java:538)
      at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:359)
      at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
      at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
      ... 114 more
  </code></pre>
  <p>Im not sure if im missing something in Azure, but I don't know what else to try, any ideas ?</p>