alibaba/nacos · warning · NacosApiException
20002
20002
Error message
Plugin configuration is required
What it means
Thrown by PUT /v3/admin/core/plugin/config when the 'config' request param (a JSON string) deserializes to a null Map<String,String>. NacosApiException ErrorCode.PARAMETER_VALIDATE_ERROR (code 20002), HTTP 400. Note: JacksonUtils.toObj of an empty/invalid string would more likely throw earlier; this null check catches the literal JSON 'null' case.
Source
Thrown at core/src/main/java/com/alibaba/nacos/core/controller/v3/PluginControllerV3.java:161
* @param configJson plugin configuration as JSON string
* @param localOnly whether only apply to local node
* @return success result
*/
@Since("3.2.0")
@PutMapping("/config")
@Secured(resource = Commons.NACOS_ADMIN_CORE_CONTEXT_V3
+ "/plugin", action = ActionTypes.WRITE, signType = SignType.CONSOLE,
apiType = ApiType.ADMIN_API)
public Result<String> updatePluginConfig(@RequestParam("pluginType") String pluginType,
@RequestParam("pluginName") String pluginName, @RequestParam("config") String configJson,
@RequestParam(value = "localOnly", defaultValue = "false") boolean localOnly)
throws NacosApiException {
validatePluginIdentifier(pluginType, pluginName);
Map<String, String> config =
JacksonUtils.toObj(configJson, new TypeReference<Map<String, String>>() {
});
if (config == null) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(),
ErrorCode.PARAMETER_VALIDATE_ERROR,
"Plugin configuration is required");
}
String pluginId = pluginType + ":" + pluginName;
unifiedPluginManager.updatePluginConfig(pluginId, config, localOnly);
return Result.success("Plugin configuration updated successfully");
}
private void validatePluginIdentifier(String pluginType, String pluginName)
throws NacosApiException {
if (StringUtils.isBlank(pluginType) || StringUtils.isBlank(pluginName)) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(),
ErrorCode.PARAMETER_VALIDATE_ERROR,
"Plugin type and name are required");
}
}
private PluginInfoVO convertToVO(PluginInfo pluginInfo) {View on GitHub (pinned to 9b989acdf1)
Solutions
- Pass a real JSON object as the config param, e.g. config={"key":"value"}.
- If no config keys are needed, pass an empty object config={} rather than null.
- Fix the client so it never serializes the config field as the JSON null literal.
Example fix
// before PUT /v3/admin/core/plugin/config?pluginType=auth&pluginName=xxx&config=null // after PUT /v3/admin/core/plugin/config?pluginType=auth&pluginName=xxx&config=%7B%7D
Defensive patterns
Strategy: validation
Validate before calling
if (configJson == null || "null".equals(configJson.trim())) {
throw new IllegalArgumentException("config must be a JSON object");
} Try / catch
try {
client.updatePluginConfig(type, name, configJson, localOnly);
} catch (NacosApiException e) {
if (e.getErrCode() == ErrorCode.PARAMETER_VALIDATE_ERROR.getCode()) { /* bad config */ }
} Prevention
- Send a real JSON object for config (use {} when empty).
- Never serialize the config as the JSON null literal.
When it happens
Trigger: Passing config=null (the JSON token null) as the 'config' request parameter. validatePluginIdentifier runs first, so pluginType/pluginName must already be non-blank to reach this check.
Common situations: Console sending config='null' string; a script defaulting the config to the JSON null literal; a frontend bug that serializes an absent config as null.
Related errors
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/c54d0b2be98524cd.
Report an issue: GitHub.