Skip to content
OpenClaw 不踩坑恶意 Skills ,企业需 Skills Registry:Nacos 3.2 发布Know more

Config Change Plugin

The config change plugin inserts custom logic before or after configuration publish, update, delete, import, and related operations. It is designed for config governance. It does not redefine the Nacos config storage model.

In unified plugin management, the type is config-change, its execution mode is CHAIN, its load phase is STANDARD, and the type is non-critical. A plugin identity is config-change:{getServiceType()}. The Nacos Server repository defines the SPI and execution aspect, but does not bundle production webhook, whitelist, or fileformatcheck implementations; those examples exist only when an external plugin JAR is on the classpath.

Typical use cases:

  • Pre-change validation: validate format, naming rules, content risk, size, or import file suffix.
  • Pre-change blocking: reject a config change and return an error message when a rule fails.
  • Post-change audit: write config change records to an audit system.
  • Post-change notification: notify downstream systems through webhooks or messaging systems.

Execution Model

The config change plugin follows an AOP-like model. Nacos represents config change operations as pointcuts, and plugins can run before or after those pointcuts.

ConceptDescription
PointcutA config change point classified by operation and source.
Before pluginRuns synchronously before the config change. It can validate, reject, or rewrite parameters.
After pluginRuns asynchronously after the config change. It is suitable for audit and notification.
OrderPlugins for the same pointcut run by getOrder() in ascending order. Lower values run earlier.

The current SPI defines these pointcuts:

PointcutMeaning
PUBLISH_BY_HTTPCreate or update config through HTTP or the console.
PUBLISH_BY_RPCCreate or update config through gRPC.
PUBLISH_BY_UNKNOWNCreate or update config when the source cannot be identified.
REMOVE_BY_HTTPDelete a single config through HTTP or the console.
REMOVE_BY_RPCDelete a single config through gRPC.
REMOVE_BY_UNKNOWNDelete a single config when the source cannot be identified.
IMPORT_BY_HTTPImport config files through HTTP or the console.
REMOVE_BATCH_HTTPBatch delete configs through HTTP or the console.

Enable and Configure a Plugin

Put the plugin JAR under ${nacos.home}/plugins, or add it to the Nacos Server startup classpath. The plugin must declare its implementation in META-INF/services/com.alibaba.nacos.plugin.config.spi.ConfigChangePluginService.

Participation in the candidate chain is controlled only by unified state for config-change:{pluginName}. The historical property only initializes state when no persisted state exists; its historical default remains false:

nacos.core.config.plugin.${configChangePluginName}.enabled=true

${configChangePluginName} must match getServiceType(). Persisted state wins. After startup, use the plugin status API or Next Console instead of maintaining a second execution gate.

New plugins declare configuration through PluginConfigSpec with this canonical prefix:

nacos.plugin.config-change.${configChangePluginName}.${itemKey}=${propertyValue}

The implementation declares each definition’s key, legacy aliases, type, default, required flag, sensitivity, and effect mode, then accepts effective values through applyConfig. Nacos also places the current effective item map in ConfigChangeConstants.PLUGIN_PROPERTIES to preserve the existing request contract.

An older binary plugin without definitions continues through the deprecated compatibility adapter and reads nacos.core.config.plugin.{pluginName}.{propertyKey}. It still loads and receives static properties, but the management APIs report configurable=false and log a migration warning on first use. ConfigChangeConfigs is deprecated but remains in its compatibility window; new code must not depend on it.

Develop a Plugin

Add the dependency:

<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-config-plugin</artifactId>
<version>${project.version}</version>
</dependency>

Implement com.alibaba.nacos.plugin.config.spi.ConfigChangePluginService:

MethodDescription
getServiceType()Stable plugin name used by configuration, logs, and plugin state management.
getOrder()Execution order. Lower values run earlier.
executeType()Return EXECUTE_BEFORE_TYPE or EXECUTE_AFTER_TYPE.
pointcutMethodNames()Return the pointcuts handled by this plugin.
execute(request, response)Run plugin logic.

ConfigChangeRequest contains the current pointcut and change parameters. Common parameters include namespaceId, group, dataId, content, srcIp, srcUser, and grayName. Nacos also passes:

ArgumentDescription
ConfigChangeConstants.ORIGINAL_ARGSOriginal method arguments.
ConfigChangeConstants.PLUGIN_PROPERTIESPlugin-specific configuration.

ConfigChangeResponse carries plugin results:

FieldDescription
successIf a Before plugin sets it to false, the config change is rejected.
msgError message returned to the caller when the change is rejected.
argsReplacement arguments provided by a Before plugin. The order and types must match the original arguments.
retValReserved return value.

A new implementation should also implement the definition, apply, and current-snapshot methods inherited from PluginConfigSpec. Validate the complete runtime map before switching it atomically. Older binaries can continue using the compatibility defaults.

Production Advice

  • Keep Before plugins lightweight and define a clear failure policy.
  • Use After plugins for audit and notification, but do not assume their side effects can roll back a config change.
  • When multiple plugins subscribe to the same pointcut, set getOrder() explicitly.
  • After changing plugin configuration, verify that every node has loaded the same plugin and configuration.
  • If a webhook URL contains a token, do not commit it to public repositories or write it to logs.

Troubleshooting

SymptomWhat to check
Plugin does not runCheck the JAR, META-INF/services, and unified plugin state; for first migration, also check the historical enabled initializer.
Before plugin does not reject a changeCheck executeType(), pointcutMethodNames(), and whether the plugin sets response.setSuccess(false).
New plugin properties are emptyCheck nacos.plugin.config-change.${serviceType}., definitions, and applyConfig.
Legacy plugin properties are emptyCheck the deprecated nacos.core.config.plugin.${serviceType}. compatibility prefix and plan migration.
Post-change notification is unstableCheck timeout, retry, and exception handling for the external system used by the After plugin.