apache/pulsar · error · RuntimeException
The log error handler cannot be changed once the appender…
Error message
The log error handler cannot be changed once the appender is started
What it means
LogAppender is a lifecycle-managed component: once start() has created the log-topic Producer (state == STARTED), swapping the ErrorHandler would leave the producer's internal failure callbacks pointing at the stale handler. setHandler therefore rejects the change with RuntimeException until stop() is called.
Solutions
- Call stop() first, then setHandler(), then start() again to apply a new handler
- Set the handler immediately after constructing the LogAppender and before any start() call
- Restructure code so the ErrorHandler is created once with mutable internals (e.g. delegate to an AtomicReference) if dynamic behavior is needed
Example fix
// before appender.start(); appender.setHandler(newHandler); // throws // after appender.setHandler(newHandler); appender.start();
Defensive patterns
Strategy: validation
Validate before calling
if (logAppender.getState() == State.STARTED) {
logAppender.stop();
}
logAppender.setHandler(newHandler);
logAppender.start(); Try / catch
try { logAppender.setHandler(newHandler); }
catch (RuntimeException e) {
if (e.getMessage().contains("cannot be changed once the appender is started")) {
log.error("stop() the appender before swapping handlers", e);
}
} Prevention
- Set the handler once, immediately after construction and before start()
- Check getState() before mutating configuration
- If dynamic behavior is needed, use a delegating ErrorHandler with an AtomicReference
- Ensure stop() is called in teardown before reconfiguration
When it happens
Trigger: Calling setHandler after start() on the same LogAppender instance; runtime code or user harness attempting to hot-swap error handling while the appender is running.
Common situations: Reconfiguring logging at runtime in a long-lived function instance; test code reusing an appender across cases without stopping it; framework upgrade path calling setHandler during restart logic while the producer is still open.
Related errors
- The log error handler cannot be set to null
- Authentication has not completed
- Classloading is not enabled
- Component cannot get state store
- Config class not found
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/839d52a7c0428690.
Report an issue: GitHub.
Appendix: source
Thrown at pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/LogAppender.java:95
}
@Override
public boolean ignoreExceptions() {
return false;
}
@Override
public ErrorHandler getHandler() {
return errorHandler;
}
@Override
public void setHandler(ErrorHandler errorHandler) {
if (errorHandler == null) {
throw new RuntimeException("The log error handler cannot be set to null");
}
if (isStarted()) {
throw new RuntimeException("The log error handler cannot be changed once the appender is started");
}
this.errorHandler = errorHandler;
}
@Override
public State getState() {
return state;
}
@Override
public void initialize() {
this.state = State.INITIALIZED;
}
@Override
public void start() {
this.state = State.STARTING;
try {View on GitHub (pinned to 820761864e)