apache/hadoop · error · IllegalStateException

Cannot initialize expiryPeriod to {} when cache is enabled.

Error message

Cannot initialize expiryPeriod to {} when cache is enabled.

What it means

PeerCache (DFSClient's DataNode socket cache) is constructed from dfs.client.socket.cache.capacity and dfs.client.socket.cache.expiryMs; the constructor allows either cache disabled (capacity 0) or enabled with a positive expiry. If capacity is non-zero (enabled) but expiryPeriod is 0, the expiry daemon could never expire peers, so it throws IllegalStateException at construction — which happens inside ClientContext the first time a DFSClient/ClientContext is created.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/PeerCache.java:105

      return time;
    }
  }

  private Daemon daemon;
  /** A map for per user per datanode. */
  private final LinkedListMultimap<Key, Value> multimap =
      LinkedListMultimap.create();
  private final int capacity;
  private final long expiryPeriod;

  public PeerCache(int c, long e) {
    this.capacity = c;
    this.expiryPeriod = e;

    if (capacity == 0 ) {
      LOG.debug("SocketCache disabled.");
    } else if (expiryPeriod == 0) {
      throw new IllegalStateException("Cannot initialize expiryPeriod to " +
         expiryPeriod + " when cache is enabled.");
    }
  }

  private boolean isDaemonStarted() {
    return daemon != null;
  }

  private synchronized void startExpiryDaemon() {
    // start daemon only if not already started
    if (isDaemonStarted()) {
      return;
    }

    daemon = new Daemon(new Runnable() {
      @Override
      public void run() {
        try {

View on GitHub (pinned to 2add963021)

Solutions

  1. Set dfs.client.socket.cache.expiryMs to a positive value (default 3000)
  2. Or disable the cache entirely: dfs.client.socket.cache.capacity=0 (expiry is then ignored)

Example fix

<!-- before: cache enabled with zero expiry -> IllegalStateException -->
<property><name>dfs.client.socket.cache.capacity</name><value>16</value></property>
<property><name>dfs.client.socket.cache.expiryMs</name><value>0</value></property>

<!-- after -->
<property><name>dfs.client.socket.cache.capacity</name><value>16</value></property>
<property><name>dfs.client.socket.cache.expiryMs</name><value>3000</value></property>
Defensive patterns

Strategy: validation

Validate before calling

// Validate socket cache settings before creating DFSClient contexts:
int cap = conf.getInt("dfs.client.socket.cache.capacity", 16);
long expiry = conf.getLong("dfs.client.socket.cache.expiryMs", 3000);
if (cap != 0 && expiry == 0) {
  throw new IllegalArgumentException(
      "dfs.client.socket.cache.expiryMs must be > 0 when capacity > 0");
}

Try / catch

try {
  FileSystem.get(hdfsUri, conf);
} catch (IllegalStateException e) {
  if (e.getMessage().contains("Cannot initialize expiryPeriod")) {
    conf.setLong("dfs.client.socket.cache.expiryMs", 3000);
    FileSystem.get(hdfsUri, conf); // retry with corrected config
  } else throw e;
}

Prevention

When it happens

Trigger: Client configuration sets dfs.client.socket.cache.capacity > 0 together with dfs.client.socket.cache.expiryMs = 0; defaults are capacity 16 and expiry 3000ms, so this requires explicit override (or a config system that zero-fills unset numeric keys).

Common situations: Performance tuning gone wrong: teams disable expiry by setting expiryMs=0 while leaving capacity on; config generators that emit 0 for 'not set' numeric values; copying configs between systems with different semantics for 0.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/6e8c8d855829a704. Report an issue: GitHub.