alibaba/nacos · error · NacosException

400

400

Error message

[Batch deRegistration] need deRegister instance is empty, instances: %s,

What it means

Thrown by NamingGrpcClientProxy.batchDeregisterService when the deregister instance list passed to getRetainInstance is null or empty (NacosException.INVALID_PARAM = 400). The client refuses to process a batch deregistration with no target instances because there is nothing to subtract from the redo set.

Source

Thrown at client/src/main/java/com/alibaba/nacos/client/naming/remote/gprc/NamingGrpcClientProxy.java:202

        synchronized (redoService.getRegisteredInstances()) {
            List<Instance> retainInstance = getRetainInstance(serviceName, groupName, instances);
            batchRegisterService(serviceName, groupName, retainInstance);
        }
    }
    
    /**
     * Get instance list that need to be Retained.
     *
     * @param serviceName         service name
     * @param groupName           group name
     * @param deRegisterInstances deregister instance list
     * @return instance list that need to be retained.
     */
    private List<Instance> getRetainInstance(String serviceName, String groupName,
        List<Instance> deRegisterInstances)
        throws NacosException {
        if (CollectionUtils.isEmpty(deRegisterInstances)) {
            throw new NacosException(NacosException.INVALID_PARAM,
                String.format(
                    "[Batch deRegistration] need deRegister instance is empty, instances: %s,",
                    deRegisterInstances));
        }
        String combinedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
        InstanceRedoData instanceRedoData =
            redoService.getRegisteredInstancesByKey(combinedServiceName);
        if (!(instanceRedoData instanceof BatchInstanceRedoData)) {
            throw new NacosException(NacosException.INVALID_PARAM, String.format(
                "[Batch deRegistration] batch deRegister is not BatchInstanceRedoData type , instances: %s,",
                deRegisterInstances));
        }
        
        BatchInstanceRedoData batchInstanceRedoData = (BatchInstanceRedoData) instanceRedoData;
        List<Instance> allRedoInstances = batchInstanceRedoData.getInstances();
        if (CollectionUtils.isEmpty(allRedoInstances)) {
            throw new NacosException(NacosException.INVALID_PARAM, String.format(
                "[Batch deRegistration] not found all registerInstance , serviceName:%s , groupName: %s",

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Guard the call: only invoke batchDeregisterService when the instances list is non-empty.
  2. If the intent is a no-op when the list is empty, short-circuit with an if-check before calling the API.
  3. Review upstream filtering logic that produces the deregister list to ensure it retains the intended instances.

Example fix

// before
namingService.batchDeregisterService(serviceName, groupName, toRemove);

// after
if (toRemove != null && !toRemove.isEmpty()) {
    namingService.batchDeregisterService(serviceName, groupName, toRemove);
}
Defensive patterns

Strategy: validation

Validate before calling

if (instances == null || instances.isEmpty()) {
    // skip batch deregister — nothing to remove
    return;
}
namingService.batchDeregisterService(serviceName, groupName, instances);

Try / catch

try {
    namingService.batchDeregisterService(serviceName, groupName, instances);
} catch (NacosException e) {
    if (e.getErrCode() == NacosException.INVALID_PARAM
        && e.getErrMsg().contains("need deRegister instance is empty")) {
        // benign — list was empty, nothing to deregister
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling namingService.batchDeregisterService(serviceName, groupName, Collections.emptyList()) or passing a null list. Can also occur if upstream code filters the list down to zero entries before forwarding it.

Common situations: Application shutdown logic that deregisters a computed set of instances which happens to be empty; a conditional that removes all instances from the list before calling batchDeregisterService; copy-paste of a register call where the list was never populated.

Related errors


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