apache/hadoop · warning · IllegalStateException

Shutdown in progress, cannot add a shutdownHook

Error message

Shutdown in progress, cannot add a shutdownHook

What it means

ShutdownHookManager.addShutdownHook throws IllegalStateException once the JVM shutdown sequence has started (the manager's own hook is draining its prioritized queue). Registering new hooks mid-shutdown is unsafe, so it is refused. This is a lifecycle race: initialization code losing to JVM termination.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ShutdownHookManager.java:301

    return list;
  }

  /**
   * Adds a shutdownHook with a priority, the higher the priority
   * the earlier will run. ShutdownHooks with same priority run
   * in a non-deterministic order.
   *
   * @param shutdownHook shutdownHook <code>Runnable</code>
   * @param priority priority of the shutdownHook.
   */
  @InterfaceAudience.Public
  @InterfaceStability.Stable
  public void addShutdownHook(Runnable shutdownHook, int priority) {
    if (shutdownHook == null) {
      throw new IllegalArgumentException("shutdownHook cannot be NULL");
    }
    if (shutdownInProgress.get()) {
      throw new IllegalStateException("Shutdown in progress, cannot add a " +
          "shutdownHook");
    }
    hooks.add(new HookEntry(shutdownHook, priority));
  }

  /**
   *
   * Adds a shutdownHook with a priority and timeout the higher the priority
   * the earlier will run. ShutdownHooks with same priority run
   * in a non-deterministic order. The shutdown hook will be terminated if it
   * has not been finished in the specified period of time.
   *
   * @param shutdownHook shutdownHook <code>Runnable</code>
   * @param priority priority of the shutdownHook
   * @param timeout timeout of the shutdownHook
   * @param unit unit of the timeout <code>TimeUnit</code>
   */
  @InterfaceAudience.Public

View on GitHub (pinned to 2add963021)

Solutions

  1. Guard registration: if (!ShutdownHookManager.get().isShutdownInProgress()) { manager.addShutdownHook(hook, prio); }
  2. Make startup lifecycle-aware: do not begin component initialization after stop() was requested (check your own stopping flag)
  3. Catch IllegalStateException around the registration call in code that can race shutdown and treat it as benign
  4. Shut down background initializer threads before System.exit so they cannot register during exit

Example fix

// before
ShutdownHookManager.get().addShutdownHook(hook, SHUTDOWN_PRIORITY);

// after
if (!ShutdownHookManager.get().isShutdownInProgress()) {
  ShutdownHookManager.get().addShutdownHook(hook, SHUTDOWN_PRIORITY);
} else {
  LOG.warn("Skipping shutdown hook registration; JVM shutdown in progress");
}
Defensive patterns

Strategy: try-catch

Validate before calling

ShutdownHookManager mgr = ShutdownHookManager.get();
if (!mgr.isShutdownInProgress()) {
  mgr.addShutdownHook(hook, priority);
}

Try / catch

try {
  ShutdownHookManager.get().addShutdownHook(hook, priority);
} catch (IllegalStateException e) {
  // JVM is shutting down: skip registration, optionally run hook inline if critical
  LOG.debug("Skipped shutdown hook registration during JVM shutdown", e);
}

Prevention

When it happens

Trigger: A lazily started service, daemon thread, or @PostConstruct registering a hook while ShutdownHookManager.get().isShutdownInProgress() is true — e.g. Ctrl+C/SIGTERM arrives while background components are still wiring up; second phase of a rolling restart beginning during shutdown.

Common situations: Servlet container hot-redeploys starting new contexts as the old JVM exits; test JVMs that finish while async threads initialize clients; applications spawned by supervisors (YARN NodeManager, systemd) receiving SIGTERM during startup.

Related errors


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