title: GMail 421 4.7.0 Try again later, closing connection
body: <p>I'am trying to find out, why it fails to send mails from my server with GMail. For this I use SwiftMailer but I can enclose the problem to the following isolated code:</p>
  <pre><code>&lt;?php
  
  $sock = stream_socket_client('tcp://smtp.gmail.com:587', $errno, $errstr);
  if (false == $sock) {
      die('error');
  }
  $server_response = fread($sock, 4096);
  echo $server_response . PHP_EOL;
  fclose($sock);
  </code></pre>
  <p>When I run this code on my local machine (Windows 10, XAMPP, PHP 5.6.24), the output is:</p>
  <pre>
  220 smtp.gmail.com ESMTP qp16sm1358626ejb.89 - gsmtp
  </pre>
  <p>So 220 means everything is fine.</p>
  <p>But when I run the exact same code on my server (Debian Jessie, PHP 5.6.38), the output is:</p>
  <pre>
  421 4.7.0 Try again later, closing connection.
  </pre>
  <p>GMail's error reference <a href="https://support.google.com/a/answer/3726730" rel="noreferrer">https://support.google.com/a/answer/3726730</a> doesn't give any advice for this error message.</p>
  <p>I also tried this on the server console without PHP and it works fine too:</p>
  <pre>
  > nc smtp.gmail.com 587
  $ 220 smtp.gmail.com ESMTP n11sm3188821wmi.15 - gsmtp
  </pre>
  <p>So I can delimit the problem</p>
  <ul>
  <li>It has nothing to do with any security settings of my GMail account (because no authentification is sent at this point)</li>
  <li>My server is not blacklisted on GMail (because the <code>nc</code> command works fine)</li>
  </ul>
  <p>Are there any settings of the php.ini that can cause this error?</p>
  <p><strong>UPDATE</strong></p>
  <p>Just for fun I set up a simple TCP server on port 587 on another machine and display the IP address of any connected client.
  There is no different if I use the above PHP client code or connecting via <code>nc</code> command.
  I don't know what could be the different for the GMail's SMTP server while conneting via the client PHP code and the <code>nc</code> command.</p>
  <p><strong>UPDATE 2</strong></p>
  <p>While enabling verbose mode in the <code>nc</code> command, could <code>DNS fwd/rev mismatch</code> be a problem?</p>
  <pre>
  > nc -v smtp.gmail.com 587
  $ DNS fwd/rev mismatch: smtp.gmail.com != wr-in-f109.1e100.net
  $ smtp.gmail.com [108.177.15.109] 587 (submission) open
  $ 220 smtp.gmail.com ESMTP z15sm4348737wrn.89 - gsmtp
  </pre>
  <p><strong>UPDATE 3</strong></p>
  <p>Run the above code with</p>
  <pre><code>$sock = stream_socket_client('tcp://wr-in-f109.1e100.net:587', $errno, $errstr);
  </code></pre>
  <p>It works, it responses with 220. But the problem is, SwiftMailer try to establish TLS security after with <code>stream_socket_enable_crypto()</code> and this fails with</p>
  <pre>
  Peer certificate CN=`smtp.gmail.com' did not match expected CN=`wr-in-f109.1e100.net'
  </pre>
  <p><strong>UPDATE 4</strong></p>
  <p>It's getting me crazy. When I use Python's TCP sockets to connect to smtp.gmail.com, GMail responses with 220:</p>
  <pre><code>import socket
  
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.connect(('smtp.gmail.com', 587))
  data = s.recv(4096)
  s.close()
  
  print data
  </code></pre>
  <p>Output:</p>
  <pre>
  220 smtp.gmail.com ESMTP p6sm8392243wmg.0 - gsmtp
  </pre>
  <p>What is the difference between Python's sockets and PHP's stream_socket_client?</p>
  <p><strong>Edit</strong>:
  The same behavior with PHP's non-streaming socket function:</p>
  <pre><code>$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  if(!is_resource($socket)) onSocketFailure(&quot;Failed to create socket&quot;);
  socket_connect($socket, &quot;smtp.gmail.com&quot;, 587)
          or onSocketFailure(&quot;Failed to connect&quot;, $socket);
  
  $line = socket_read($socket, 1024, PHP_NORMAL_READ);
  
  var_dump($line);
  socket_close($socket);
  </code></pre>
  <p><strong>UPDATE 5</strong></p>
  <p>Now I think it is a problem with IPv6. I'am not a big C programmer but I tried to understand the PHP's implementation.</p>
  <p>Have a look at</p>
  <ul>
  <li><a href="https://github.com/php/php-src/blob/master/main/streams/xp_socket.c#L782" rel="noreferrer">xp_socket.c</a> the function <code>php_tcp_sockop_connect</code> uses <code>php_network_connect_socket_to_host</code></li>
  <li><a href="https://github.com/php/php-src/blob/master/main/network.c#L767" rel="noreferrer">network.c</a> which is implemented here</li>
  <li>It use <code>php_network_getaddresses</code></li>
  <li>and this function use <code>getaddrinfo</code></li>
  </ul>
  <p><code>php_network_connect_socket_to_host</code> iterates of the list of host addresses and tries to connect to it. If its success, it stops with looping.</p>
  <p>I don't tried it out with C but I think the following Python code does the same:</p>
  <pre><code>import socket
  print socket.getaddrinfo(&quot;smtp.gmail.com&quot;, 587)
  </code></pre>
  <p>Which prints</p>
  <pre>
  [
   (10, 1, 6, '', ('2a00:1450:400c:c0c::6d', 587, 0, 0)),
   (10, 2, 17, '', ('2a00:1450:400c:c0c::6d', 587, 0, 0)),
   (10, 3, 0, '', ('2a00:1450:400c:c0c::6d', 587, 0, 0)),
   (2, 1, 6, '', ('108.177.15.109', 587)),
   (2, 2, 17, '', ('108.177.15.109', 587)),
   (2, 3, 0, '', ('108.177.15.109', 587))
  ]
  </pre>
  <p>(I formatted the line for better reading)</p>
  <p>As you can see, there are three IPv6 addresses on the top of the list and <code>php_network_connect_socket_to_host</code> try these IPv6 adresses first before it comes to the IPv4 addresses.</p>
  <p>So what happens when I try to connect directly to the first IPv6 address?</p>
  <pre><code>&lt;?php
  
  $sock = stream_socket_client('tcp://[2a00:1450:400c:c02::6c]:587', $errno, $errstr);
  if (false == $sock) {
      die('error');
  }
  $server_response = fread($sock, 4096);
  echo $server_response . PHP_EOL;
  fclose($sock);
  </code></pre>
  <p>The output is:</p>
  <pre>
  421 4.7.0 Try again later, closing connection.
  </pre>
  <p>This SO question is related to this observation: <a href="https://stackoverflow.com/questions/63160968/why-i-cant-send-emails-using-smtp-gmail-com587-on-ipv6">Why I can&#39;t send emails using smtp.gmail.com:587 on ipv6?</a></p>