How to Resolve Python SSH Error "ssh: Could not resolve hostname [hostname]: nodename nor servname provided, or not known" & socket.gaierror
Whether you're trying to connect to a remote server via SSH or making network connections within a Python script, encountering errors like ssh: Could not resolve hostname ...: nodename nor servname provided, or not known
or socket.gaierror: [Errno -2] Name or service not known
can be frustrating. Both errors fundamentally indicate the same problem: your system was unable to translate the provided hostname or address into a usable IP address.
This guide explains the common causes for these name resolution failures and provides systematic troubleshooting steps and solutions for both SSH and Python socket scenarios.
Understanding the Error: Hostname Resolution Failure
Your computer needs an IP address (like 192.168.1.100
or 203.0.113.5
) to establish a network connection. When you provide a hostname (like myserver.example.com
, raspberrypi
, or localhost
), the system needs to resolve it – find the corresponding IP address. This resolution process involves:
- Checking local configuration files (like
/etc/hosts
on Linux/macOS orC:\Windows\System32\drivers\etc\hosts
on Windows). - Using local network discovery protocols (like mDNS/Bonjour/Avahi, often used for
.local
addresses). - Querying configured Domain Name System (DNS) servers.
The "nodename nor servname provided, or not known" (often seen with SSH) and socket.gaierror: [Errno -2] Name or service not known
(seen in Python) errors mean this resolution process failed for the hostname you provided.
Common Causes
- Typos: Simple spelling mistakes in the hostname or IP address are very common.
- DNS Server Issues: Your configured DNS server might be down, unreachable, slow, or misconfigured, preventing it from resolving external hostnames.
- Local Network Resolution: For devices on your local network (like a Raspberry Pi), protocols like mDNS might not be running or responding correctly, or the device name might be slightly different than expected (e.g., needing a
.local
suffix). - Incorrect Hosts File: The
/etc/hosts
(Linux/macOS) or Windowshosts
file might have incorrect or missing entries, especially if you rely on it for local name resolution. - SSH Config Errors: Typos or syntax errors in your
~/.ssh/config
file can lead to incorrect hostnames being used by SSH. - Network Connectivity: Basic network issues like no route to the host or firewall rules blocking DNS queries or the connection itself can manifest as resolution failures.
Troubleshooting Steps
Verify Hostname/IP and Check for Typos
Double-check the exact hostname or IP address you are trying to connect to. Ensure there are no spelling mistakes or extra characters.
Basic Network Connectivity (ping
)
Try pinging the hostname or IP address to see if your machine can reach it at a basic network level.
ping server.example.com
ping 192.168.1.100
If ping
fails ("unknown host" or timeouts), it points towards a resolution or network reachability problem. If it works with the IP but not the hostname, it's likely a DNS or local resolution issue.
Check DNS Resolution (nslookup
/ dig
)
Use tools to directly query your DNS server (if applicable).
nslookup server.example.com
# or
dig server.example.com
Check if these return the correct IP address. If they fail or return incorrect information, suspect DNS issues.
Check SSH Command Syntax (-p
for Port)
A common SSH mistake is using the wrong syntax for specifying a port.
- Correct:
ssh -p <PORT> user@hostname
orssh user@hostname -p <PORT>
- Incorrect:
ssh user@hostname:<PORT>
(The colon syntax is not standard for SSH port)
# Correct ways to specify port 22 (default) or 2222
ssh -p 22 [email protected]
ssh [email protected] -p 2222
Solutions
Correct Typos (Hostname, IP, SSH Config)
Carefully review the hostname/IP address in your command or script. Examine your ~/.ssh/config
file for any typos in HostName
directives.
Fix SSH Syntax (Use -p PORT
)
If connecting via SSH and specifying a non-standard port, always use the -p
option before the port number, not a colon after the hostname.
Address DNS Issues (Restart Resolver, Check Config)
- Restart Local DNS Cache/Service: Sometimes the local DNS resolver gets stuck.
- macOS:
sudo killall -HUP mDNSResponder
- Linux (systemd-resolved):
sudo systemctl restart systemd-resolved
- Linux (nscd):
sudo systemctl restart nscd
- Windows:
ipconfig /flushdns
(in an Administrator Command Prompt)
- macOS:
- Check System DNS Configuration:
- Linux: Examine
/etc/resolv.conf
. Ensurenameserver
entries point to valid, reachable DNS servers. - macOS: System Preferences/Settings -> Network -> Select Interface (Wi-Fi/Ethernet) -> Advanced... -> DNS.
- Windows: Network Adapter Properties -> IPv4 Settings -> DNS server addresses.
- Try temporarily setting your DNS to a public server like Google (
8.8.8.8
,8.8.4.4
) or Cloudflare (1.1.1.1
) to see if your default DNS is the problem.
- Linux: Examine
Address Local Network Issues (Try .local
, Check Services)
- Try
.local
Suffix: For devices on your local network (Raspberry Pi, other Macs/Linux boxes), mDNS/Bonjour/Avahi often resolves hostnames ending in.local
.ssh [email protected]
ping my-macbook.local - Check mDNS/Avahi Services: Ensure the mDNS responder (macOS), Avahi daemon (Linux), or Bonjour service (Windows, if installed) is running on both the client and the target device if you rely on
.local
names.
Correct /etc/hosts
(or Windows hosts
) File
The hosts file allows you to manually map IP addresses to hostnames, overriding DNS for those specific entries. This is useful for local development or accessing local devices by name without relying on mDNS.
- Location:
- Linux/macOS:
/etc/hosts
- Windows:
C:\Windows\System32\drivers\etc\hosts
- Linux/macOS:
- Editing: You usually need administrator/root privileges to edit this file (
sudo nano /etc/hosts
or edit as Administrator on Windows). - Format: Each line should be
IP_ADDRESS hostname [optional_aliases]
# Example entry for a local Raspberry Pi
192.168.1.150 mypi mypi.local
# Default localhost entries (usually present)
127.0.0.1 localhost
::1 localhost - Ensure there are no incorrect entries overriding the hostname you're trying to reach. Add entries if you need to define local-only names.
Fix ~/.ssh/config
File
If using SSH configuration, ensure correct syntax.
# Correct format example
Host myalias
HostName real_server_address_or_ip # Check this for typos
User myusername
Port 2222 # Optional, if not 22
# IdentityFile ~/.ssh/id_rsa_server # Optional path to key
# Incorrect format (e.g., colon after Host) should be avoided
# Host myalias: # <-- Incorrect colon
Check Firewalls and Network Routes
Ensure no firewall (on your machine, the remote machine, or network devices) is blocking DNS queries (usually UDP/TCP port 53) or the specific connection attempt (e.g., TCP port 22 for SSH). Also, verify basic network reachability if ping
fails.
Solving socket.gaierror
in Python
This error in Python code using modules like socket
, requests
, or urllib
has the same root causes as the SSH error – name resolution failure.
Verify Connection Strings
Most importantly, double-check the hostname or IP address string you are passing to functions like socket.connect()
, socket.create_connection()
, socket.getaddrinfo()
, requests.get()
, urllib.request.urlopen()
, etc. Typos are extremely common.
import socket
import requests
hostname = "myserver.examplle.com" # Typo: 'examplle' instead of 'example'
port = 80
try:
# Example with socket
# socket.create_connection((hostname, port), timeout=5)
# Example with requests
response = requests.get(f"http://{hostname}:{port}", timeout=5)
except socket.gaierror as e:
print(f"Caught socket.gaierror: {e}") # Output: [Errno -2] Name or service not known
except requests.exceptions.ConnectionError as e:
print(f"Caught requests ConnectionError often wrapping gaierror: {e}")
Solution: Correct the hostname
variable.
Check /etc/hosts
for localhost
Ensure your hosts file (see 4.5) contains a correct entry mapping 127.0.0.1
to localhost
. Most systems have this by default, but if it's missing or commented out, resolving localhost
can fail.
import socket
try:
ip = socket.gethostbyname('localhost')
print(f"localhost resolves to: {ip}") # Should be 127.0.0.1
except socket.gaierror as e:
print(f"Failed to resolve localhost: {e}. Check your hosts file.")
Using socket.gethostbyname('')
often implicitly tries to resolve the machine's own hostname, which also relies on proper system configuration or hosts file entries.
Conclusion
The "nodename nor servname provided, or not known" and socket.gaierror: [Errno -2]
errors both indicate a failure in resolving a hostname/address to an IP address. Troubleshooting involves systematically checking:
- Typos in the hostname, IP, or configuration files (
~/.ssh/config
). - Correct SSH command syntax (use
-p
for port). - DNS functionality (restart local resolver, check server settings).
- Local network resolution (
.local
suffix, hosts file). - Basic network connectivity (
ping
, firewalls).
When encountering the socket.gaierror
in Python, pay close attention to the hostname string passed to network functions, as typos are the most frequent cause, but DNS and hosts file issues are also relevant.