Search code examples
pythondjangoemailgmailstarttls

Error sending email in django through gmail


I am trying to send a mail using django through gmail.

Following is my settings.py code:

EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'mypassword'
EMAIL_USE_TLS = True

view.py I am using method send_mail():

send_mail(subject, contact_message, emailfrom, emailto)

When I execute the code & enter details in my contact form & hit submit. I get the below error:

smtplib.SMTPNotSupportedError: STARTTLS extension not supported by server.    

Please suggest!


Solution

  • I don't know Gmail, and I don't know Django, but I hope the following explanations will help you.

    A quick analysis shows that your situation is kind of odd. There is a simple method to test what capabilities / extension an SMTP server provides: Get a command line telnet client, connect to the server in question and query its capabilities. The following shows how this is done in Linux, but it's basically the same with Windows:

    root@spock:~# telnet smtp.gmail.com 587              <-- Type this on the command line
    Trying 74.125.71.109...                              <-- This is output
    Connected to gmail-smtp-msa.l.google.com.            <-- This is output
    Escape character is '^]'.                            <-- This is output
    220 smtp.gmail.com ESMTP s196sm2489285wmb.6 - gsmtp  <-- This is output
    EHLO localhost.com                                   <-- **YOU** must type this
    250-smtp.gmail.com at your service, [46.83.27.246]   <-- The following lines are output
    250-SIZE 35882577
    250-8BITMIME
    250-STARTTLS                                         <-- NOTE THIS LINE
    250-ENHANCEDSTATUSCODES
    250-PIPELINING
    250-CHUNKING
    250 SMTPUTF8
    

    The key points here are the second command line parameter to the telnet command which designates which port to use, and the EHLO command you type (make sure you really type EHLO and not HELO which is another command).

    As you can see from the example, smtp.gmail.com definitely supports the STARTTLS command / extension. I have tested this in a normal environment; my Linux box is behind a NAT router which is the usual setup for private households and small companies. No port forwarding or other special configuration is in place.

    So the first thing I would recommend is that you repeat this simple test at your place. Then,

    • If you get the same result as me, especially if the output you get also contains the line 250-STARTTLS, there is absolutely no explanation what happens here besides errors in Django itself. Are you using the most recent version? I can't help you here, because I never have used it and I don't know anything about it.

    • If the line 250-STARTTLS is not in the output you get, something completely weird must go on. As my example shows, STARTTLS is supported at least for clients at my place, and there is no reason why it shouldn't be supported for clients at your place.

    • Exceptions might be China or similar countries where governments try to prevent the usage of encryption. So I could imagine that Google turns off the STARTTLS extension based on geo-blocking when a client from such a country connects. But I really don't know! People who do are encouraged to leave a comment ...

    • Perhaps you are using a proxy which disturbs the communication between your client (Django) and the SMTP server.

    I you still haven't found the problem, you could do the following:

    • You could try port 25 instead of port 587. I have verified that smtp.gmail.com supports STARTTLS on port 25 as well. With most email clients, it doesn't matter if you use port 25 or port 587. You should be able to make Django use port 25 by saying EMAIL_PORT = 25 in your configuration file.

    • You could try to use implicit TLS (most often called SSL) instead of the explicit STARTTLS. The port which is usually used for this is 465. To implement this, say EMAIL_PORT = 465, EMAIL_USE_TLS = False and EMAIL_USE_SSL = True in your configuration file.