Pushing a configuration change to every node at once risks bringing down the entire cluster if the change contains an error. Canary release mitigates this risk by delivering the change to a small set of nodes first. After you verify the change, you gradually roll it out to all remaining nodes.
MSE Nacos supports two canary release strategies:
| Strategy | How it works | Best for |
|---|---|---|
| IP-based | Target specific node IP addresses | Small business systems with stable IPs |
| Tag-based | Target nodes by application tag (key-value pair) | Kubernetes or any environment where IPs change frequently |
Prerequisites
Before you begin, make sure that you have:
Nacos Client 2.x or later
Release a configuration with IP-based canary
IP-based canary release targets specific IP addresses to receive the new configuration. Nodes not in the IP list continue to use the current official version.
This method works for small clusters but has two limitations:
In Nacos Client 1.x, the server cannot accurately obtain the client IP when the connection passes through an SLB instance.
In Kubernetes environments, pod IP addresses change when nodes are rebuilt, which can cause the canary release to target the wrong nodes.
For dynamic environments, use tag-based canary release instead.
Create an IP-based canary configuration
Log on to the MSE console and select a region in the top navigation bar.
In the left-side navigation pane, choose Microservices Registry > Instances.
On the Instances page, click the name of the target instance.
In the left-side navigation pane, choose Configuration Management > Configurations.
Find the target configuration and click Edit in the Actions column.
In the Edit Configuration panel, set Release Type to IP-based Canary Release.

Click the Application Node IP input box and select the IP addresses for the canary release. You can also type IP addresses manually. The input supports autocomplete.
NoteIP addresses listed here are the IPs of nodes that subscribe to this configuration. Separate multiple IP addresses with commas (,).
Edit the configuration content, then click Canary Release.
In the Comparison of Configuration Content dialog box, verify the Current Official Version and Content To Be Released, then click Release.
View the canary configuration
Navigate to the Configurations page of the target instance (steps 1-4 above).
Find the configuration with an active canary release and click Edit in the Actions column.
In the Edit Configuration panel, click the Beta(IP) tab to view the canary release details.

Stop or promote the canary release
On the Beta(IP) tab of the Edit Configuration panel:
Stop the canary release: Click Stop Canary Release. The canary configuration is discarded and all nodes continue using the official version.
Promote to full release: Click Full Release. In the Comparison of Configuration Content dialog box, confirm the configuration and click Full Release. The canary configuration becomes the new official version and the canary release ends.
Release a configuration with tag-based canary
Tag-based canary release matches nodes by application tags instead of IP addresses. Tags persist across pod restarts and node rebuilds, which makes this strategy more resilient in Kubernetes and other dynamic environments.
Tag-based canary releases require MSE Nacos 2.2.3.3 or later. You must upgrade your engine to version 2.2.3.3 or later.
Custom application tags require open-source Nacos Client 2.3.2 or later.
Tag injection through environment variables requires Nacos Client 2.4.2 or later.
Step 1: Set application tags on the client
Assign tags to application nodes in key-value format. You can set tags through properties, JVM parameters, or environment variables. If the same key is defined in multiple places, the priority order is: properties > JVM parameters > environment variables.
nacos.config.gray.label is the built-in default tag key for canary releases.
// Option 1: Set through properties
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "<your-nacos-endpoint>");
properties.put("project.name", "<your-app-name>");
properties.put("nacos.config.gray.label", "<your-canary-tag>");
// Option 2: Set as a JVM parameter
// -Dnacos.config.gray.label=<your-canary-tag>
// Option 3: Set as an environment variable
// nacos_config_gray_label=<your-canary-tag>
// Create the config service and subscribe to a configuration
NacosConfigService configService = new NacosConfigService(properties);
String dataId = "<your-data-id>";
String group = "<your-group>";
configService.addListener(dataId, group, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("Received config: " + configInfo);
}
});Replace the following placeholders with actual values:
| Placeholder | Description | Example |
|---|---|---|
<your-nacos-endpoint> | Nacos server endpoint | mse-xxx.nacos.mse.aliyuncs.com:8848 |
<your-app-name> | Application name | order-service |
<your-canary-tag> | Canary release tag value | canary-v2 |
<your-data-id> | Nacos configuration data ID | com.example.app.properties |
<your-group> | Nacos configuration group | DEFAULT_GROUP |
Step 2: Verify listener tags on the server
After the client connects with tags, verify that the server recognizes them. Open the listener list for the target configuration. Each listener displays its associated tags.

Step 3: Release a tag-based canary configuration
Click Edit Configuration and set Release Type to Tag-based Canary Release.
Select an existing key-value tag pair. The console displays the number of nodes that match the selected tag.

Edit the configuration content and click Canary Release.
Step 4: Verify and expand the release
After releasing the canary version:
Verify the canary group: On the Listener Query tab, check which configuration version each node received.
View canary details: On the Configuration Details tab, review the current canary version content.
Expand the release scope: After confirming the canary group is healthy, expand the tag value to include more nodes. Repeat until all target nodes are covered.
Promote to full release: Click Full Release to make the canary configuration the new official version. The canary version is stopped automatically.
Roll back if needed: If a problem occurs, click Stop Canary Release to discard the canary configuration. All nodes revert to the official version.
Run parallel canary versions
A single configuration can have multiple active versions at the same time:
One official version
One IP-based canary version
Multiple tag-based canary versions (up to 5 by default)
Version matching priority
When a node requests a configuration, MSE Nacos evaluates versions in this order:
IP-based canary version -- If the node IP matches the canary IP list, this version is returned.
Tag-based canary version -- If no IP match exists, the system checks tag-based canary versions sorted by the
priorityfield (higher value = higher priority). If priority values are equal, versions are sorted by name.Official version -- If no canary version matches, the official version is returned.
Check the matched configuration version for each node on the Listener Query page in the MSE console.
Parallel canary versions require MSE Nacos 2.3.0 or later. A maximum of 5 tag-based canary versions can exist per configuration by default. If this limit is exceeded, new canary releases are blocked.
Advanced tag configuration
Set multiple tags
Nacos supports injecting multiple key-value tag pairs into an application through the nacos.app.conn.labels parameter. Use the format "k1=v1,k2=v2,k3=v3".
// Option 1: Set through properties
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "<your-nacos-endpoint>");
properties.put("project.name", "<your-app-name>");
properties.put("nacos.app.conn.labels", "app=order-service,site=hangzhou-c,env=staging");
// Option 2: Set as a JVM parameter
// -Dnacos.app.conn.labels="app=order-service,site=hangzhou-c,env=staging"
// Option 3: Set as an environment variable
// nacos_app_conn_labels="app=order-service,site=hangzhou-c,env=staging"
NacosConfigService configService = new NacosConfigService(properties);
String dataId = "<your-data-id>";
String group = "<your-group>";
configService.addListener(dataId, group, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("Received config: " + configInfo);
}
});Implement a custom tag collector (SPI)
For dynamic or complex tag logic, implement the com.alibaba.nacos.common.labels.LabelsCollector SPI interface and register it as a service.
package com.example.labels;
import com.alibaba.nacos.common.labels.LabelsCollector;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class CustomLabelsCollector implements LabelsCollector {
@Override
public String getName() {
return "custom-labels";
}
@Override
public Map<String, String> collectLabels(Properties properties) {
Map<String, String> labels = new HashMap<>();
// Add custom logic to determine labels
labels.put("env", System.getenv("DEPLOY_ENV"));
labels.put("region", System.getenv("DEPLOY_REGION"));
return labels;
}
@Override
public int getOrder() {
return 1;
}
}To use the implementation, publish it as a service.
Tag format requirements
Tag keys and values support: uppercase and lowercase letters, digits, underscores (_), hyphens (-), and periods (.). Tags in other formats are ignored.
When specifying multiple key-value pairs with nacos.app.conn.labels, use the format "k1=v1,k2=v2,k3=v3". Entries without a value are ignored. For example, "k1=v1,k2" results in only k1=v1 being parsed.
Best practices for tag planning
Plan application tags based on the scope of business impact to enable gradual rollout and minimize risk.
Tag by application name: Release to non-critical applications first. After confirming no issues, expand to core applications.
Tag by traffic group: Isolate a group of canary machines at the traffic ingress for internal users. Assign a dedicated canary tag to these machines to validate changes with internal traffic before exposing them to production users.