Coffee beans and Java logo

When using the java/JVM DNS caching, you should know that java caches DNS entries by default, which is abnormal for most client and server applications. It also strange that does not honor the DNS TTL when it caches. The DNS system has had TTL in it since 1987 (see RFC 1035) and most applications will not cache DNS entries. Most applications just rely on the local UNIX DNS resolvers which do not cache DNS entries. The resolvers do get to experience the timing out of entries indirectly through the DNS servers they query. DNS servers do cache entries along with TTLs, and the DNS servers do honor the DNS TTL. Java does not honor the DNS TTL but rather caches entries according to its own whim. Earlier versions cache DNS records permanently. Java versions since 1.6 behave differently:

  • By default, Java versions 1.4 and 1.5 cache DNS indefinitely until JVM/java instance is restarted.
  • By default, Java versions 1.6 and 1.7 without a security manager set have a 30 second timeout on DNS cache entries.
  • By default, Java versions 1.6 and 1.7 with a security manager set have an indefinite timeout on DNS cache entries.

The problems indefinite caching causes are two:

  1. With round-robin, failover, and load-balanced environments, DNS address cut-overs are not picked up until you restart the JVM or java instance. If you forget to do this or miss doing this on any JVMs, you are likely to have an service outage.
  2. Performance problems. The cache was not intended to boost performance and in fact, with the way java uses memory, it actually may do more harm than good to utilize JVM memory for a DNS cache.

The reason why java versions 1.4 and 1.5 cache indefinitely is a security feature. According to Oracle documentation, less than a 30 second caching or no caching can result in DNS cache poisoning. This is only partially true, as DNS cache poisoning can occur with a greater than 30 second TTL DNS record, in certain environments, exposed to the internet, with older, unpatched DNS servers.

And why would you use java where you query DNS servers that you don’t trust or are exposed to UDP from unknown foreign DNS servers? If you do that, you possibly have an exposure no matter what you set the time-out to.

You should always be able to trust your DNS server for local internal domain lookups (like the corporate LDAP global DNS entry). If you can trust your DNS server, you can turn off caching. According to IBM PK20100:

IP Address security caching was intended to address concerns of DNS spoofing. These issues are not prevalent in an enterprise environment where DNS servers in use are trusted. If security caching is causing problems, it should be disabled. The Java IP address security cache was not intended as a performance improvement.

© Copyright 2020 Rex Consulting, Inc. – All rights reserved