alibaba/nacos · warning · IllegalArgumentException

Plugin selection for exclusive type '{}' requires restart. U

Error message

Plugin selection for exclusive type '{}' requires restart. Update '{}' instead.

What it means

validateStateChangeInternal throws IllegalArgumentException (mapped by setPluginEnabled to NacosApiException HTTP 400 / PARAMETER_VALIDATE_ERROR 20002) when toggling a plugin whose PluginType.isExclusive() is true. Exclusive types allow only one active plugin, selected at startup via a selection property — they cannot be switched at runtime. Exposed via PUT /v3/console/plugin/status.

Source

Thrown at core/src/main/java/com/alibaba/nacos/core/plugin/PluginManager.java:773

        refreshAllCriticalFlags();
    }
    
    private void validateStateChangeInternal(PluginInfo info, boolean enabled) {
        validateRuntimeChangeSupported(info, "state");
        if (info.isEnabled() == enabled) {
            return;
        }
        PluginType type = info.getPluginType();
        if (type.isCritical() && policyRegistry.isActive(type)) {
            Map<String, Boolean> targetStates = getCurrentStates();
            targetStates.put(info.getPluginId(), enabled);
            String validationError = getCriticalValidationError(type, targetStates);
            if (validationError != null) {
                throw new IllegalArgumentException(validationError);
            }
        }
        if (type.isExclusive()) {
            throw new IllegalArgumentException("Plugin selection for exclusive type '"
                + type.getType() + "' requires restart. Update '" + getSelectionProperty(type)
                + "' instead.");
        }
    }
    
    private long countEnabledPlugins(PluginType type) {
        return pluginRegistry.values().stream()
            .filter(info -> type == info.getPluginType() && info.isEnabled()).count();
    }
    
    private void validateCriticalStates(Map<String, Boolean> targetStates) {
        for (PluginType type : PluginType.values()) {
            String validationError = getCriticalValidationError(type, targetStates);
            if (validationError != null) {
                LOGGER.error("[PluginManager] {}", validationError);
                throw new IllegalStateException(validationError);
            }
        }

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Do not use the runtime toggle for exclusive plugin types.
  2. Set the selection property named in the error (e.g. nacos.core.auth.plugin.type / the type's selector) in application.properties and restart the server.
  3. Use GET /v3/console/plugin to inspect which type a plugin belongs to and whether it is exclusive.

Example fix

// before
PUT /v3/console/plugin/status?pluginType=auth&pluginName=ldap&enabled=true
// after: set selection property and restart
# application.properties
nacos.core.auth.plugin.type=ldap
Defensive patterns

Strategy: validation

Validate before calling

PluginDetailVO detail = pluginClient.getDetail(pluginType, pluginName);
if (detail.getPluginType().isExclusive()) {
    throw new IllegalStateException("exclusive type " + pluginType
        + " cannot be toggled at runtime; set its selection property and restart");
}

Try / catch

try {
    pluginClient.setEnabled(type, name, enabled, localOnly);
} catch (NacosApiException e) {
    if (e.getErrCode() == 20002 && e.getMessage().contains("exclusive type")) {
        // route the user to set the selection property + restart instead
    } else { throw e; }
}

Prevention

When it happens

Trigger: PUT /v3/console/plugin/status enabling a different plugin of an exclusive type (e.g. enabling auth:ldap when auth:nacos is already the selected auth plugin), or toggling any exclusive-type plugin.

Common situations: Trying to switch the active auth / datasource-dialect / similar exclusive plugin through the runtime enable API instead of configuration; not knowing a type is exclusive.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/82eb82b15697c637. Report an issue: GitHub.