alibaba/nacos · warning · NacosApiException
RESOURCE_NOT_FOUND
RESOURCE_NOT_FOUND
Error message
Plugin not found: {pluginId} What it means
PluginManager.setPluginEnabled throws NacosApiException(NacosException.NOT_FOUND 404, ErrorCode.RESOURCE_NOT_FOUND 20004) when the pluginId is absent from pluginRegistry. The pluginId is composed as {type}:{name} (e.g. "trace:test", "auth:nacos"). This method backs PUT /v3/console/plugin/status.
Source
Thrown at core/src/main/java/com/alibaba/nacos/core/plugin/PluginManager.java:241
* @throws NacosApiException if plugin not found or is critical
*/
public void setPluginEnabled(String pluginId, boolean enabled) throws NacosApiException {
setPluginEnabled(pluginId, enabled, false);
}
/**
* Set plugin enabled/disabled state.
*
* @param pluginId plugin ID
* @param enabled whether to enable
* @param localOnly if true, only update local node without Raft sync (for emergency use)
* @throws NacosApiException if plugin not found or is critical
*/
public void setPluginEnabled(String pluginId, boolean enabled, boolean localOnly)
throws NacosApiException {
PluginInfo info = pluginRegistry.get(pluginId);
if (info == null) {
throw new NacosApiException(NacosException.NOT_FOUND, ErrorCode.RESOURCE_NOT_FOUND,
"Plugin not found: " + pluginId);
}
try {
validateRuntimeChangeSupported(info, "state");
validateStateChangeInternal(info, enabled);
} catch (IllegalArgumentException e) {
throw new NacosApiException(NacosException.INVALID_PARAM,
ErrorCode.PARAMETER_VALIDATE_ERROR, e.getMessage());
}
if (info.isEnabled() == enabled) {
LOGGER.debug("[PluginManager] Plugin {} already has enabled={}", pluginId, enabled);
return;
}
// LocalOnly mode: only update local memory, skip cluster sync
if (localOnly) {
LOGGER.warn(View on GitHub (pinned to 9b989acdf1)
Solutions
- Call GET /v3/console/plugin/list first and use an exact pluginId/type+name from the result.
- Ensure the plugin jar is present on the server classpath and loaded at startup.
- Check the server log for plugin load failures.
Example fix
// before PUT /v3/console/plugin/status?pluginType=auth&pluginName=ldap&enabled=false // after (verify id first) GET /v3/console/plugin/list?pluginType=auth -> use the real pluginName
Defensive patterns
Strategy: validation
Validate before calling
// Resolve exact plugin id from the server before toggling
List<PluginInfoVO> plugins = pluginClient.list("auth");
boolean exists = plugins.stream().anyMatch(p -> p.getPluginName().equals(name));
if (!exists) throw new IllegalArgumentException("unknown plugin auth:" + name);
pluginClient.setEnabled("auth", name, enabled, localOnly); Try / catch
try {
pluginClient.setEnabled(type, name, enabled, localOnly);
} catch (NacosApiException e) {
if (e.getErrCode() == 20004 && e.getMessage().contains("Plugin not found")) {
// refresh the plugin list and retry with the real id
} else { throw e; }
} Prevention
- Always list plugins first and use the exact type+name.
- Ensure the plugin jar is deployed before toggling.
- Check startup logs for plugin load errors.
When it happens
Trigger: PUT /v3/console/plugin/status?pluginType=auth&pluginName=ldap for a plugin that is not installed/registered; a typo in the type or name; calling before startup plugin scanning finished.
Common situations: Plugin jar missing from the classpath/plugins dir; using a plugin name that differs from its registered id; the plugin type abbreviation is wrong (e.g. "authentication" instead of "auth").
Related errors
- PARAMETER_VALIDATE_ERROR
- RESOURCE_NOT_FOUND
- baseType must not be null
- subtype must not be null
- typeName must not be empty
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/1172df38d874cd4f.
Report an issue: GitHub.