Skip to main content

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:

  1. Checking local configuration files (like /etc/hosts on Linux/macOS or C:\Windows\System32\drivers\etc\hosts on Windows).
  2. Using local network discovery protocols (like mDNS/Bonjour/Avahi, often used for .local addresses).
  3. 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 Windows hosts 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 or ssh 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)
  • Check System DNS Configuration:
    • Linux: Examine /etc/resolv.conf. Ensure nameserver 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.

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
  • 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:

  1. Typos in the hostname, IP, or configuration files (~/.ssh/config).
  2. Correct SSH command syntax (use -p for port).
  3. DNS functionality (restart local resolver, check server settings).
  4. Local network resolution (.local suffix, hosts file).
  5. 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.