alibaba/druid · error · DruidRuntimeException

No Observer(such as PoolUpdater) specified.

Error message

No Observer(such as PoolUpdater) specified.

What it means

NodeListener.init() requires an Observer (typically a PoolUpdater) to be registered before it can begin watching for node changes, because NodeListener extends Observable and forwards detected node add/remove events to that observer. Calling init() with observer==null means the listener would have nowhere to deliver events, so Druid refuses to start.

Source

Thrown at core/src/main/java/com/alibaba/druid/pool/ha/node/NodeListener.java:55

    /**
     * The method implements the detail update logic.
     */
    public abstract List<NodeEvent> refresh();

    /**
     * Do some cleanup.
     */
    public abstract void destroy();

    /**
     * Add the given PoolUpdater as the Observer.
     *
     * @see #setObserver(Observer)
     */
    public void init() {
        if (observer == null) {
            throw new DruidRuntimeException("No Observer(such as PoolUpdater) specified.");
        }
        this.addObserver(observer);
    }

    /**
     * Fire the refresh() method and notify the Observer.
     *
     * @see #refresh()
     * @see #update(List)
     */
    public void update() {
        update(refresh());
    }

    /**
     * Notify the Observer.
     */
    public void update(List<NodeEvent> events) {

View on GitHub (pinned to fa8dc99126)

Solutions

  1. Call nodeListener.setObserver(new PoolUpdater(dataSource)) before nodeListener.init().
  2. Prefer the HighAvailableDataSource high-level API, which wires the observer automatically, over manual NodeListener construction.
  3. Verify the observer field is non-null in a startup sanity check so misconfiguration fails early with your own message.

Example fix

// before
NodeListener listener = new ZookeeperNodeListener();
listener.init(); // throws 'No Observer specified.'

// after
NodeListener listener = new ZookeeperNodeListener();
listener.setObserver(new PoolUpdater(haDataSource));
listener.init();
Defensive patterns

Strategy: validation

Validate before calling

if (nodeListener.getObserver() == null) {
    throw new IllegalStateException("set a PoolUpdater via nodeListener.setObserver(...) before init()");
}
nodeListener.init();

Type guard

public static boolean readyToInit(NodeListener l) {
    return l.getObserver() != null;
}

Prevention

When it happens

Trigger: Constructing a NodeListener (e.g. ZookeeperNodeListener, FileNodeListener) and calling init() (directly or via the HA DataSource bootstrap that calls selector.init() -> NodeListener.init()) without first calling setObserver(...).

Common situations: Custom integration wiring HighAvailableDataSource manually and forgetting the PoolUpdater; upgrading Druid versions where the wiring API changed; copying example code that omitted the observer step.

Related errors


AI-assisted analysis of alibaba/druid@fa8dc99126 (2026-08-14). Data as JSON: /api/errors/ee1b8b54693f1b6d. Report an issue: GitHub.