jenkinsci/jenkins · warning · RestartRequiredException

{0} plugin is already installed. Jenkins needs to be restart

Error message

{0} plugin is already installed. Jenkins needs to be restarted for the update to take effect.

What it means

RestartRequiredException is thrown when a plugin with the given short name is already installed and removeExisting is false. Jenkins cannot hot-deploy over an existing plugin without either removing it first or restarting. The message indicates the plugin is already present and a restart is needed for the update to take effect.

Source

Thrown at core/src/main/java/hudson/PluginManager.java:946

            try {
                sn = strategy.getShortName(arc);
            } catch (AbstractMethodError x) {
                LOGGER.log(WARNING, "JENKINS-12753 fix not active: {0}", x.getMessage());
                p = strategy.createPluginWrapper(arc);
                sn = p.getShortName();
            }
            PluginWrapper pw = getPlugin(sn);
            if (pw != null) {
                if (removeExisting) { // try to load disabled plugins
                    for (Iterator<PluginWrapper> i = plugins.iterator(); i.hasNext();) {
                        pw = i.next();
                        if (sn.equals(pw.getShortName())) {
                            i.remove();
                            break;
                        }
                    }
                } else {
                    throw new RestartRequiredException(Messages._PluginManager_PluginIsAlreadyInstalled_RestartRequired(sn));
                }
            }
            if (!Lifecycle.get().supportsDynamicLoad()) {
                throw new RestartRequiredException(Messages._PluginManager_LifecycleDoesNotSupportDynamicLoad_RestartRequired());
            }
            if (p == null) {
                p = strategy.createPluginWrapper(arc);
            }
            if (p.supportsDynamicLoad() == YesNoMaybe.NO)
                throw new RestartRequiredException(Messages._PluginManager_PluginDoesntSupportDynamicLoad_RestartRequired(sn));

            // there's no need to do cyclic dependency check, because we are deploying one at a time,
            // so existing plugins can't be depending on this newly deployed one.

            plugins.add(p);
            if (p.isActive()) {
                activePlugins.add(p);
                ((UberClassLoader) uberClassLoader).clearCacheMisses();

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Set removeExisting=true in the deploy call to replace the existing plugin (only works if the plugin is disabled).
  2. Restart Jenkins after installing the update instead of relying on dynamic load.
  3. Use the Update Center's standard upgrade flow which handles restart scheduling.

Example fix

// before — dynamic load fails because plugin exists
pluginManager.dynamicLoad(arc);

// after — remove existing disabled plugin first or schedule restart
PluginWrapper existing = pluginManager.getPlugin(sn);
if (existing != null && !existing.isActive()) {
    // only removable if not active
    pluginManager.getPlugins().remove(existing);
}
pluginManager.dynamicLoad(arc);
Defensive patterns

Strategy: validation

Validate before calling

PluginWrapper existing = pluginManager.getPlugin(sn);
if (existing != null && !removeExisting) {
    // must restart or remove existing first
    throw new RestartRequiredException("Plugin " + sn + " already installed; restart required.");
}

Try / catch

try {
    pluginManager.dynamicDeploy(p, arc, removeExisting);
} catch (RestartRequiredException e) {
    // Schedule restart and inform user
    listener.getLogger().println("Restart required: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling dynamicDeploy/dynamicLoad with a plugin short name that matches an already-loaded PluginWrapper, when removeExisting is not set to true.

Common situations: Attempting to install or update a plugin via the REST API or UI while the same plugin is already active and the deployment doesn't specify removal of the existing one.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/da59f2d0bf161761. Report an issue: GitHub.