Fixing java.net.UnknownHostException: A Guide to DNS Issues in Java

beginner Java2026-04-26| Java (JDK 8-21), Linux (Ubuntu/Debian/CentOS), Windows Server, Docker, Kubernetes

Error Message

java.net.UnknownHostException: api.service-provider.com
#java#networking#dns#troubleshooting

The Scenario

It usually happens when you're least expecting it. Your Spring Boot microservice is humming along, and then the logs explode with a wall of red text. Instead of a successful API response, you see this:

Exception in thread "main" java.net.UnknownHostException: api.service-provider.com
    at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:229)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.base/java.net.Socket.connect(Socket.java:609)

This error means the Java Virtual Machine (JVM) is lost. It has a hostname, but it cannot find the corresponding IP address to send its data. Without that IP, the connection simply cannot start.

Why did the lookup fail?

Diagnosis is half the battle. Most DNS failures in Java fall into three buckets:

- **Infrastructure:** The DNS server is unreachable, or the server has lost its internet connection.
- **Configuration:** A developer made a typo, or a private internal host isn't registered in the public DNS records.
- **JVM Caching:** The remote server changed its IP address, but your JVM is stubbornly clinging to an old, invalid record.

Step 1: The Sanity Check

Always start with the basics. Run a manual lookup from the terminal of the machine where the application is running. Use nslookup or dig:

nslookup api.service-provider.com

If this command returns an error, the problem isn't your Java code—it's a system-level networking issue. Watch out for simple typos in your application.yml. A common mistake is a trailing space or a transposed letter, like api.servcie-provider.com, which will trigger the exception every time.

Step 2: Using the Hosts File for Local Testing

Sometimes you need to connect to a development server that doesn't have a public DNS entry yet. In these cases, you can force a mapping in the operating system's hosts file.

On Linux or macOS: Open /etc/hosts with root privileges.

sudo nano /etc/hosts
# Add a manual entry:
1.2.3.4 api.service-provider.com

On Windows: Edit C:\Windows\System32\drivers\etc\hosts as an Administrator.

This approach bypasses DNS servers entirely. It tells the OS to resolve that specific name to that specific IP immediately.

Step 3: Troubleshooting Docker and Kubernetes

Containerized environments add a layer of complexity to networking. If your app is in a container, UnknownHostException often stems from isolated networks.

Docker Networking

If you are trying to connect to another container on the same host, ensure they share the same Docker network. You can also force the container to use a reliable DNS provider like Google (8.8.8.8) or Cloudflare (1.1.1.1):

docker run --dns 8.8.8.8 my-java-app

Kubernetes CoreDNS

Inside a cluster, short names only work within the same namespace. If you need to reach a service in a different namespace, you must use the Fully Qualified Domain Name (FQDN):

# Standard format: service-name.namespace.svc.cluster.local
auth-service.production.svc.cluster.local

Step 4: Taming the JVM DNS Cache

The most overlooked culprit is the JVM's internal cache. By default, if a Security Manager is active, the JVM caches successful DNS lookups forever (TTL = -1). If your cloud provider migrates a load balancer to a new IP, your application will keep knocking on a dead door.

You can force the JVM to refresh its cache every 60 seconds by adding this startup argument:

-Dsun.net.inetaddr.ttl=60

If you cannot change the startup script, set it programmatically at the very beginning of your main method:

java.security.Security.setProperty("networkaddress.cache.ttl" , "60");

Verification: Testing the Resolution

Run this small snippet to confirm the JVM can see the host. It eliminates the complexity of your full application framework:

import java.net.InetAddress;

public class DNSCheck {
    public static void main(String[] args) {
        try {
            String host = "api.service-provider.com";
            System.out.println("Resolving: " + host);
            System.out.println("IP: " + InetAddress.getByName(host).getHostAddress());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Prevention Strategies

Network reliability is a core part of distributed systems. When planning your network layout, use a tool like this Subnet Calculator to map out CIDR blocks. This helps prevent overlapping subnets, which often cause the routing loops that lead to DNS failures.

Finally, always implement retries with exponential backoff. DNS is inherently flaky. Sometimes a single retry 50ms later is all you need to clear a temporary glitch and keep your application running smoothly.

Related Error Notes