OSError at /password-reset/ [Errno 101] Network is unreachable

Hi All, I am encountering difficulty when trying to add password reset email generation functionality to my Django Blog. Upon entering the email associated with the user’s account into my password reset form, and clicking the submit button, after a long delay of around 60 seconds I receive the OSError at /password-reset [Errno 101] Network is unreachable error page. I also receive a similar error when trying to just send emails manually using the shell as i have detailed in my steps below.

The steps I have taken are:

  1. Created a new Gmail account specifically for this purpose
  2. Setup two factor authentication on the gmail account
  3. Generated an “app password” from the google account (select app = mail, select device = other, hand keyed in “Python Django Application”
  4. Created an env.py file in the root directory of my project, importing the os module
  5. Added EMAIL_USER, and EMAIL_PASS variables to the env.py file, initially these variables respectively contained the newly created gmail account address, and the google-generated application passwords, both as strings
  6. Added the following variables to my settings.py:

settings.py:
EMAIL_BACKEND = ‘django.core.mail.backends.smtp.EmailBackend’
EMAIL_HOST = ‘smtp.gmail.com
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.environ.get(‘EMAIL_USER’)
EMAIL_HOST_PASSWORD = os.environ.get(‘EMAIL_PASS’)

where env.py contains:

env.py:
import os
EMAIL_USER = ‘newgmailaccountaddress@gmail.com’
EMAIL_PASS = ‘thegeneratedapppasswordgooglegenerated’

Steps Taken to resolve the issue:

  1. Tried sending an email manually in the shell per the Quick Example - I receive the same error:

OSError: [Errno 101] Network is unreachable

in the shell with some additional comments amongst the verbose shell output

Don't bother creating the network connection if there's nobody to send to. and # We failed silently on open(). # Trying to send would be pointless.

  1. Tried different combinations of string values for EMAIL_HOST_PASSWORD variable in settings.py:
  • Attempt 1: Use os.environ.get(EMAIL_PASS) where EMAIL_PASS is a variable in my env.py file, set to a string containing the 16 character app password Gmail generated for “my device” (which I specified as Other/ then manually typed in “Python Django application” when setting up in my Google Account)

  • Attempt 2: Directly set EMAIL_HOST_PASSWORD to a string containing the 16 character app password Gmail generated for “my device” (i.e. not using an env.py file - I realize this approach is not secure compared to attempt 1 and can expose sensitive password data)

  • Attempt 3: Directly set EMAIL_HOST_PASSWORD to a string containing the actual password for the Gmail account (I realize this approach is even less secure than attempt 2)

  1. Tried different settings for the EMAIL_PORT variable in settings.py :
  • Attempt 1: 587
  • Attempt 2: 25 (same error)
  • Attempt 3: 465 (same error)

Any help or guidance you can provide is much appreciated, thanks

Depending upon the environment in which you’re working, there could be a couple different causes - but generally, this error is cause by something outside the program itself. It’s unlikely that this error is being caused by Django

For example, some of the causes might be:

  • No internet connectivity
  • Local traffic routing problems
  • Firewalls blocking access to external ports 587, 25, 465
  • Firewalls blocking access to smtp.gmail.com
  • DNS resolution error giving you a wrong address

You can try a quick check to see if you can ping smtp.gmail.com. (However, this is not a guaranteed check since some ISPs block ICMP requests to the internet.) You can also try to telnet to smtp.gmail.com at 587 to see if you get a response.

You can also check this by installing an email client (such as Thunderbird) and configuring it to connect to gmail.

Hi Ken - thanks for this - I tried a quick check by pinging smtp.gmail.com and my results were below (note I initially made a typo but it still pinged, and the correct address is in the second ping) - would this help diagnose the problem more?

I’m initially just hesitant try the telnet & thunderbird options simply because I am not yet familiar with them but will certainly try these as well if the ping test is not helping determine a next step, thanks again for your help:

That confirms that you have basic connectivity - the next step is to ensure that you can get to smtp.email.com on port 587, and for that you will need to use something that will communicate on that port.

Hi Ken, I tried the telnet approach, initially it failed as I didn’t specify the port - but then when I specified port 587 i think it worked & i got the 220 response (below) which i understand means the SMTP port 587 is not blocked…

I’m just not exactly sure how to proceed again unfortunately, any guidance much appreciated as always, thanks


Next step would be to confirm that Python is allowed out through Windows Firewall. (Quick test for this would be to temporarily turn the firewall off while you’re testing your app.)

Also, what versions of Python and Django are you using?

Thanks Ken, I turned off the firewall & went back to run the tests below, unfortunately they all returned the same error as before:

Tests 1-4 Password set to the Application password generated by google

  1. Run manually from shell per quick example instructions (using env.py & os.environ.get approach for EMAIL_HOST & EMAIL_PASSWORD variables)
  2. Run from development server as part of the blog application (using env.py & os.environ.get approach for EMAIL_HOST & EMAIL_PASSWORD variables)
  3. Run from development server as part of the blog application (directly populating EMAIL_HOST & EMAIL_PASSWORD variables in settings.py i.e. without using env.py/os.environ.get)
  4. Run from shell (directly populating EMAIL_HOST & EMAIL_PASSWORD variables in settings.py i.e. without using env.py/os.environ.get)

Tests 5-6 Password set to the actual password I would use myself to log into the email account

  1. Run from shell (directly populating EMAIL_HOST & EMAIL_PASSWORD variables in settings.py i.e. without using env.py/os.environ.get)
  2. Run from development server as part of the blog application (directly populating EMAIL_HOST & EMAIL_PASSWORD variables in settings.py i.e. without using env.py/os.environ.get)

I’ve also done a re-check of all the variables ensuring that the emails & passwords etc are typo-free, but it just doesn’t seem to want to work…

Actually Ken I’m just wondering would this be a problem with google’s smtp servers, when i check this link Is Smtp.gmail.com Down Right Now? - Smtp.gmail.com not working it says server status down

Ok, first to be completely clear - the error you’re receiving has nothing to do with the actual credentials you are passing. If connectivity was working and the credentials are wrong, you would get a different error. So whatever the problem is, this is not related to the user / password combination.

Again, what versions of Python and Django are you using here?

Are you running this from a virtual environment, or a global python installation?

The only next step that I can see would be to use tcpdump / wireshark / Microsoft Message Analyzer to track the network traffic associated with this.

(I don’t know for sure, but that site appears to be checking for https connectivity, not smtp. I’m not having any problems with Gmail itself.)

Sorry I completely forgot about the Python & Django version - Python is 3.8.11 and Django is 4.0.2

I am running it from a gitpod workspace (I’m not sure if that is a virtual environment or a global python installation?)

Are you running all these other manual tests from that same gitpod workspace?

Yes I’m running all of it from the git pod workspace, and the shell tests were run from a terminal within that workspace as well

I don’t know what to tell you at this point.

If I had to chase this down, I’d be pulling out all the stops to find out what’s happening. That would include:

  • Trying the code from a different site / host / location / environment.
  • Trying Thunderbird within that gitpod to verify complete and correct connectivity
  • Adding all possible logging to track what’s going on in the system
  • Using a network trace tool (tcpdump, wireshark, Microsoft Message Analyzer) to capture the actual network traffic being passed.

Ok thanks Ken, I’ll have a think & hopefully be able to try some of these. Thanks again for all the help on this so far, much appreciated