Python 2: SMTPServerDisconnected: Connection unexpectedly closed
Question: I have a small problem with a sending Email in Python:

    
    
    #me == my email address
    #you == recipient's email address
    me = "some.email@gmail.com"
    you = "some_email2@gmail.com"
    
    # Create message container - the correct MIME type is multipart/alternative.
    msg = MIMEMultipart('alternative')
    msg['Subject'] = "Alert"
    msg['From'] = me
    msg['To'] = you
    
    # Create the body of the message (a plain-text and an HTML version).
    html = '<html><body><p>Hi, I have the following alerts for you!</p></body></html>'
    
    # Record the MIME types of both parts - text/plain and text/html.
    part2 = MIMEText(html, 'html')
    
    # Attach parts into message container.
    # According to RFC 2046, the last part of a multipart message, in this case
    # the HTML message, is best and preferred.
    msg.attach(part2)
    
    # Send the message via local SMTP server.
    s = smtplib.SMTP('aspmx.l.google.com')
    # sendmail function takes 3 arguments: sender's address, recipient's address
    # and message to send - here it is sent as one string.
    s.sendmail(me, you, msg.as_string())
    s.quit()
    

So before now, my program, didn't give me an error, but it also didn't send me
an Email. And now python give me an error:

    
    
    SMTPServerDisconnected: Connection unexpectedly closed
    

How can I fix that?


Answer: Most probably the gmail server rejected the connection after the data command
(very nasty of them to do so at this stage :). The actual message is most
probably this one:

    
    
        retcode (421); Msg: 4.7.0 [ip.octets.listed.here      15] Our system has detected an unusual rate of
        4.7.0 unsolicited mail originating from your IP address. To protect our
        4.7.0 users from spam, mail sent from your IP address has been temporarily
        4.7.0 rate limited. Please visit
        4.7.0  https://support.google.com/mail/answer/81126 to review our Bulk Email
        4.7.0 Senders Guidelines. qa9si9093954wjc.138 - gsmtp
    

How do I know that? Because I've tried it :) with the `s.set_debuglevel(1)`,
which prints the SMTP conversation and you can see firsthand what's the issue.

You've got two options here:

  1. Continue using that relay; [as explained by Google](https://support.google.com/a/answer/176600?hl=en), it's unencrypted gmail-to-gmail only, and you have to un-blacklist your ip through their procedure

  2. The most fool-proof option is to switch to TLS with authentication

Here's how the changed source looks like:

    
    
    # skipped your comments for readability
    import smtplib
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    
    me = "some.email@gmail.com"
    my_password = r"your_actual_password"
    you = "some.email2@gmail.com"
    
    msg = MIMEMultipart('alternative')
    msg['Subject'] = "Alert"
    msg['From'] = me
    msg['To'] = you
    
    html = '<html><body><p>Hi, I have the following alerts for you!</p></body></html>'
    part2 = MIMEText(html, 'html')
    
    msg.attach(part2)
    
    # Send the message via gmail's regular server, over SSL - passwords are being sent, afterall
    s = smtplib.SMTP_SSL('smtp.gmail.com')
    # uncomment if interested in the actual smtp conversation
    # s.set_debuglevel(1)
    # do the smtp auth; sends ehlo if it hasn't been sent already
    s.login(me, my_password)
    
    s.sendmail(me, you, msg.as_string())
    s.quit()
    

Now, if try to 'cheat' the system and send with a different (non-gmail)
address it's gonna a) require you to connect to a different hostname (some of
the MX records for gmail), then b) stop you and close the connection on the
grounds of blacklisted ip, and c) do reverse DNS, DKIM and lots of other
countermeasures to make sure you're actually in control of the domain you
presented in the MAIL FROM: address.

Finally, there's also option 3) - use any other email relaying service, there
are tons of good ones :)

