Looking up a hostname from an IP address is useful when you need to turn connection logs, firewall hits, or audit data into a name that is easier to recognize than the numeric address alone.
Python exposes reverse lookups through the socket module. socket.gethostbyaddr() asks the system resolver for reverse DNS data and returns a tuple containing the primary hostname, any aliases, and the address list associated with that result.
Reverse DNS is optional, so a valid IPv4 or IPv6 address can still return no hostname when no PTR record exists for it. Validating the input with ipaddress.ip_address() keeps malformed input separate from a missing reverse record, and socket.herror remains the expected failure when the address is valid but no reverse name is available.
Related: Get an IP address from a hostname
Related: Get a hostname from a URL
$ python3 Python 3.14.3 Type "help", "copyright", "credits" or "license" for more information. >>>
>>> import socket
>>> result = socket.gethostbyaddr("198.51.100.24")
>>> result
('resolver-01.edge.example.net', ['24.100.51.198.in-addr.arpa'], ['198.51.100.24'])
The tuple format is (hostname, aliaslist, ipaddrlist), so the first value is the primary hostname returned by the resolver.
Use socket.getfqdn("198.51.100.24") when you only need the resolved display name instead of the full tuple.
#!/usr/bin/env python3 import ipaddress import socket import sys if len(sys.argv) != 2: raise SystemExit(f"Usage: {sys.argv[0]} <ip-address>") try: address = str(ipaddress.ip_address(sys.argv[1])) except ValueError as exc: raise SystemExit(f"Invalid IP address: {exc}") try: hostname, aliases, addresses = socket.gethostbyaddr(address) except socket.herror as exc: raise SystemExit(f"No reverse DNS hostname found for {address}: {exc}") print(f"IP address: {address}") print(f"Primary hostname: {hostname}") if aliases: print("Aliases:") for alias in aliases: print(f" {alias}") print("Resolved addresses:") for resolved in addresses: print(f" {resolved}")
ipaddress.ip_address() accepts both IPv4 and IPv6 strings and raises ValueError for malformed input before the lookup runs.
$ python3 ip-to-hostname.py 198.51.100.24 IP address: 198.51.100.24 Primary hostname: resolver-01.edge.example.net Aliases: 24.100.51.198.in-addr.arpa Resolved addresses: 198.51.100.24
The published examples use masked documentation IP addresses and hostnames, so your live resolver output will differ. The same script works with IPv6 addresses such as 2001:db8:100::24 when a reverse record exists.
$ python3 ip-to-hostname.py 192.0.2.1 No reverse DNS hostname found for 192.0.2.1: [Errno 1] Unknown host
Documentation, lab, and many private addresses have no PTR record, so a valid address can still fail reverse lookup.