apache/hadoop · error · IllegalArgumentException
shutdownHook cannot be NULL
Error message
shutdownHook cannot be NULL
What it means
ShutdownHookManager is Hadoop's prioritized, timeout-capable replacement for Runtime.addShutdownHook. addShutdownHook(Runnable, int) rejects a null hook with IllegalArgumentException before touching the hook registry. The hook object was never constructed — usually a factory, DI field, or optional component that produced null.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ShutdownHookManager.java:298
return o2.priority - o1.priority;
}
});
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 shutdownHookView on GitHub (pinned to 2add963021)
Solutions
- Find who passes null: check the argument expression at the call site
- Construct the Runnable before registering, or skip registration entirely when the component is disabled
- Add Objects.requireNonNull(hook, "shutdownHook") at your own call boundary for a clearer failure
- If the component may legitimately be absent, branch: if (cleanup != null) manager.addShutdownHook(cleanup, prio);
Example fix
// before
ShutdownHookManager.get().addShutdownHook(cleanupTask, 50); // cleanupTask null when init failed
// after
if (cleanupTask != null) {
ShutdownHookManager.get().addShutdownHook(cleanupTask, 50);
} Defensive patterns
Strategy: validation
Validate before calling
Objects.requireNonNull(hook, "shutdownHook must be constructed before registration"); ShutdownHookManager.get().addShutdownHook(hook, priority);
Try / catch
try { ShutdownHookManager.get().addShutdownHook(hook, priority); } catch (IllegalArgumentException e) { /* hook was null: fix construction, skip registration */ } Prevention
- Construct the hook Runnable at declaration site so a null cannot flow into registration
- Skip registration for disabled/failed components instead of passing null
- Use Objects.requireNonNull with a message at your own API boundary for clearer failures
When it happens
Trigger: ShutdownHookManager.get().addShutdownHook(null, priority) — typically hook built lazily (e.g. hook = service != null ? service.newCleanup() : null) and the guard branch lost.
Common situations: Registering cleanup for a service whose initialization failed earlier; optional plugins disabled via config injecting null; test wiring that forgot to instantiate the hook runnable.
Related errors
- Shutdown in progress, cannot add a shutdownHook
- Shutdown in progress, cannot remove a shutdownHook
- key + ": Stream is closed!"
- Stream closed
- %s: Stream is closed!
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/395a0552f66d3bb2.
Report an issue: GitHub.