apache/pulsar · error · IllegalArgumentException

Not support to set executeExistingDelayedTasksAfterShutdownP

Error message

Not support to set executeExistingDelayedTasksAfterShutdownPolicy, it is always false

What it means

SingleThreadNonConcurrentFixedRateScheduler always behaves as if executeExistingDelayedTasksAfterShutdownPolicy is false: delayed tasks are never executed after shutdown. The setExecuteExistingDelayedTasksAfterShutdownPolicy method therefore unconditionally throws IllegalArgumentException, rejecting any attempt to change this fixed policy.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/SingleThreadNonConcurrentFixedRateScheduler.java:216

    public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean flag) {
        throw new IllegalArgumentException("Not support to set continueExistingPeriodicTasksAfterShutdownPolicy, it is"
                + " always false");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
        return false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean flag) {
        throw new IllegalArgumentException("Not support to set executeExistingDelayedTasksAfterShutdownPolicy, it is"
                + " always false");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
        return false;
    }

    /**
     * {@inheritDoc}
     * Since the method "remove(runnable)" of DelayedWorkQueue is expensive if the tasks in the queue is not the same
     * type, we denied the remove policy.
     */
    @Override
    public void setRemoveOnCancelPolicy(boolean value) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Remove the call; the scheduler intentionally discards delayed tasks after shutdown.
  2. Guard the call so it is only applied to schedulers that support the policy.
  3. If delayed tasks must survive shutdown, use ScheduledThreadPoolExecutor or redesign shutdown handling (cancel tasks explicitly and reschedule on a new executor).
  4. Catch IllegalArgumentException if the configuration path must remain compatible with arbitrary executor types.

Example fix

// before
scheduler.setExecuteExistingDelayedTasksAfterShutdownPolicy(true);
// after
if (scheduler instanceof java.util.concurrent.ScheduledThreadPoolExecutor) {
    ((java.util.concurrent.ScheduledThreadPoolExecutor) scheduler).setExecuteExistingDelayedTasksAfterShutdownPolicy(true);
}
Defensive patterns

Strategy: try-catch

Validate before calling

static boolean supportsShutdownPolicies(java.util.concurrent.ScheduledExecutorService s) {
    return !(s instanceof org.apache.pulsar.common.util.SingleThreadNonConcurrentFixedRateScheduler);
}

Type guard

static boolean isPolicyConfigurable(java.util.concurrent.ScheduledExecutorService s) {
    return s instanceof java.util.concurrent.ScheduledThreadPoolExecutor;
}

Try / catch

try {
    scheduler.setExecuteExistingDelayedTasksAfterShutdownPolicy(flag);
} catch (IllegalArgumentException e) {
    LOG.info("Scheduler {} does not support delayed-task shutdown policy: {}", scheduler, e.getMessage());
}

Prevention

When it happens

Trigger: Calling setExecuteExistingDelayedTasksAfterShutdownPolicy(true or false) on a SingleThreadNonConcurrentFixedRateScheduler, usually from generic ScheduledExecutorService configuration code that applies policy tuning to any scheduler it manages.

Common situations: Copied executor-tuning code (from ScheduledThreadPoolExecutor usage) applied to this custom scheduler; frameworks that centrally configure executors for an application that also instantiates Pulsar's scheduler; migration from java.util.concurrent schedulers.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/d3ddfe517f7d83fc. Report an issue: GitHub.