Python socket.error: [Errno 104] Connection reset by peer

avatar
Borislav Hadzhiev

Last updated: Apr 11, 2024
3 min

banner

# Python socket.error: [Errno 104] Connection reset by peer

The Python error "socket.error: [Errno 104] Connection reset by peer" occurs when the remote server immediately drops the connection rather than initiating the usual handshake.

Use a try/except statement to handle the error.

main.py
from socket import error as SocketError import errno import urllib.request url = 'http://www.python.org/' try: with urllib.request.urlopen(url, timeout=10) as f: print(f.read()) except SocketError as err: if err.errno != errno.ECONNRESET: # The error is NOT a ConnectionResetError raise # ๐Ÿ‘‡๏ธ Handle the ConnectionResetError here print('ConnectionResetError occurred')

handle connection reset error using try except

The code sample uses a try/except statement to handle the potential ConnectionResetError.

We first make an HTTP request in the try block.

If an error occurs, the except block runs.

We check if the error is not equal to errno.ECONNRESET.

If the remote server hasn't reset the connection, then the error is NOT ConnectionResetError, so we re-raise it.

You can handle the ConnectionResetError exception right after the if statement.

For example, you could re-issue the request.

You can also explicitly handle the ConnectionResetError in the except block.

main.py
import urllib.request url = 'http://www.python.org/' try: with urllib.request.urlopen(url, timeout=10) as f: print(f.read()) raise ValueError('hi') except ConnectionResetError: print('A ConnectionResetError occurred') except TimeoutError: print('A TimeoutError occurred') except BaseException as e: print('A generic error occurred', e)

If a ConnectionResetError occurs, the first except block runs.

The second except block handles a TimeoutError exception.

The last except block handles generic errors that are neither ConnectionResetError nor TimeoutError.

# Try to wait for N seconds between the requests

Another thing you can try is to wait for N seconds between the requests as the remote server might have throttled you.

main.py
import errno from socket import error as SocketError import urllib.request import time url = 'http://www.python.org/' try: # โœ… Wait for 2 seconds... time.sleep(2) with urllib.request.urlopen(url, timeout=10) as f: print(f.read()) except SocketError as err: if err.errno != errno.ECONNRESET: # The error is NOT a ConnectionResetError raise # ๐Ÿ‘‡๏ธ Handle the ConnectionResetError here print('ConnectionResetError occurred')

The code sample uses the time.sleep() method to wait for 2 seconds before issuing the HTTP request.

The remote server you are making requests to might have limited the number of connections.

This is often a cause of the error because it occurs when the remote server immediately drops the connection rather than initiating the usual handshake.

You can test different values for the time.sleep() method.

This approach is especially useful when you have to issue multiple requests (e.g. in a for loop).

You can also try to check how many requests you are allowed to issue per (second, hour or day) in the API's documentation.

# Try setting the headers when making the request

The server might've also dropped the connection because it detected that the client is a Python script.

You can set the User-Agent header to try to get around this.

Let's look at an example that uses the requests library.

First, make sure you have the requests module installed.

shell
pip install requests # Or with pip3 pip3 install requests

Now import and use the module as follows.

main.py
import errno from socket import error as SocketError import requests url = 'http://www.python.org/' headers = { "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)" } try: response = requests.get(url, headers=headers, timeout=10) print(response.text) print(response.status_code) except SocketError as err: if err.errno != errno.ECONNRESET: # The error is NOT a ConnectionResetError raise # ๐Ÿ‘‡๏ธ Handle the ConnectionResetError here print('ConnectionResetError occurred')

If you expect a JSON response, you would use the response.json() method instead of accessing the response.text attribute.

main.py
parsed = response.json() print(parsed)

The headers dictionary sets the User-Agent header to simulate an HTTP request that is made by a browser and not a Python script.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev