apache/hadoop · error · IllegalStateException
Can't re-install the signal handlers.
Error message
Can't re-install the signal handlers.
What it means
SignalLogger.INSTANCE.register(Logger) installs Hadoop's handlers for TERM, HUP and INT (built on sun.misc.Signal) that log received signals and chain to the previous handler. The class keeps a one-shot 'registered' flag and throws IllegalStateException on a second registration, because re-installing would chain duplicate handlers and double-log every signal.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/SignalLogger.java:70
* Handle an incoming signal.
*
* @param signal The incoming signal
*/
@Override
public void handle(SignalUtil.Signal signal) {
log.error("RECEIVED SIGNAL {}: SIG{}", signal.getNumber(), signal.getName());
prevHandler.handle(signal);
}
}
/**
* Register some signal handlers.
*
* @param log The log4j logfile to use in the signal handlers.
*/
public void register(final Logger log) {
if (registered) {
throw new IllegalStateException("Can't re-install the signal handlers.");
}
registered = true;
StringBuilder bld = new StringBuilder();
bld.append("registered UNIX signal handlers for [");
final String[] SIGNALS = {"TERM", "HUP", "INT"};
String separator = "";
for (String signalName : SIGNALS) {
try {
new Handler(signalName, log);
bld.append(separator)
.append(signalName);
separator = ", ";
} catch (Exception e) {
log.debug("Error: ", e);
}
}
bld.append("]");
log.info(bld.toString());View on GitHub (pinned to 2add963021)
Solutions
- Register once per JVM, at process startup (e.g. in main()), not per component or per test
- In tests, use @BeforeAll / one-time fixtures, or fork a JVM per test to get a clean SignalLogger
- Catch IllegalStateException and ignore it if a dependency may already have registered handlers
- Search dependency stack traces for 'registered UNIX signal handlers' INFO line to see who registered first
Example fix
// before
public void init() {
SignalLogger.INSTANCE.register(LOG); // called by every component/test -> second call throws
}
// after
private static final AtomicBoolean signalLogged = new AtomicBoolean(false);
public void init() {
if (signalLogged.compareAndSet(false, true)) {
SignalLogger.INSTANCE.register(LOG);
}
} Defensive patterns
Strategy: try-catch
Try / catch
try {
SignalLogger.INSTANCE.register(LOG);
} catch (IllegalStateException alreadyRegistered) {
// another component in this JVM already installed the handlers; safe to continue
} Prevention
- Call SignalLogger.INSTANCE.register(log) exactly once per JVM, from main() or a static initializer
- In test suites, register in @BeforeAll (not @BeforeEach) or fork a JVM per test
- When embedding multiple Hadoop-based libraries, agree on a single owner for signal handler registration
- Remember this only works on Sun/Oracle JVMs where sun.misc.Signal exists — guard for other JVMs
When it happens
Trigger: Two components in one JVM each calling SignalLogger.INSTANCE.register(log) — e.g. embedding two Hadoop-based clients, a library that self-registers plus application code that registers again, or test setups that register per test in the same forked JVM.
Common situations: JUnit suites where @BeforeEach registers signal handlers without reset; combining HBase/Hadoop/YARN client libs in one process; SDK re-initialization code paths that call register() on every connect.
Related errors
- GoogleHadoopFileSystem has been closed or not initialized.
- query component in Path not supported {}
- URI: {} is an invalid Har URI. Expecting har://<scheme>-<hos
- Shutdown in progress, cannot add a shutdownHook
- Shutdown in progress, cannot remove a shutdownHook
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/d46ca1a85887cdce.
Report an issue: GitHub.