alibaba/nacos · error · NacosRuntimeException

400

400

Error message

Current service %s is ephemeral service, can't register persistent instance.

What it means

Thrown by PersistentClientOperationServiceImpl.registerInstance when the service singleton IS ephemeral but the registration targets the persistent path. Error code 400 (INVALID_PARAM) via NacosRuntimeException. This is the mirror of the ephemeral-path rejection: a persistent instance can only be registered against a persistent (ephemeral=false) service.

Source

Thrown at naming/src/main/java/com/alibaba/nacos/naming/core/v2/service/impl/PersistentClientOperationServiceImpl.java:110

    private final CPProtocol protocol;
    
    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    
    private final ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
    
    private static final int INITIAL_CAPACITY = 128;
    
    public PersistentClientOperationServiceImpl(final PersistentIpPortClientManager clientManager) {
        this.clientManager = clientManager;
        this.protocol = ApplicationUtils.getBean(ProtocolManager.class).getCpProtocol();
        this.protocol.addRequestProcessors(Collections.singletonList(this));
    }
    
    @Override
    public void registerInstance(Service service, Instance instance, String clientId) {
        Service singleton = ServiceManager.getInstance().getSingleton(service);
        if (singleton.isEphemeral()) {
            throw new NacosRuntimeException(NacosException.INVALID_PARAM,
                String.format(
                    "Current service %s is ephemeral service, can't register persistent instance.",
                    singleton.getGroupedServiceName()));
        }
        final InstanceStoreRequest request = new InstanceStoreRequest();
        request.setService(service);
        request.setInstance(instance);
        request.setClientId(clientId);
        final WriteRequest writeRequest = WriteRequest.newBuilder().setGroup(group())
            .setData(ByteString.copyFrom(serializer.serialize(request)))
            .setOperation(DataOperation.ADD.name())
            .build();
        
        try {
            protocol.write(writeRequest);
            Loggers.RAFT.info("Client registered. service={}, clientId={}, instance={}", service,
                clientId, instance);
        } catch (Exception e) {

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Align the instance ephemeral flag with the service: register ephemeral instances against ephemeral services.
  2. Recreate the service with ephemeral=false if persistent instances are intended.
  3. Explicitly set instance.setEphemeral(true) if the service is ephemeral.
  4. Query the service metadata to verify its ephemeral flag before registering.

Example fix

// before — service is ephemeral, instance is persistent
Instance inst = new Instance();
inst.setEphemeral(false); // mismatch!
namingService.registerInstance(service, inst);

// after — match the ephemeral service
Instance inst = new Instance();
inst.setEphemeral(true);
namingService.registerInstance(service, inst);
Defensive patterns

Strategy: validation

Validate before calling

Service singleton = ServiceManager.getInstance().getSingleton(service);
if (singleton.isEphemeral()) {
    // service is ephemeral — cannot register persistent instance
    // either set instance.ephemeral=true or recreate service as persistent
    instance.setEphemeral(true);
}
persistentClientOperationService.registerInstance(service, instance, clientId);

Try / catch

try {
    persistentClientOperationService.registerInstance(service, instance, clientId);
} catch (NacosRuntimeException e) {
    if (e.getErrCode() == NacosException.INVALID_PARAM
            && e.getMessage().contains("ephemeral service")) {
        // route to ephemeral registration path instead
        ephemeralClientOperationService.registerInstance(service, instance, clientId);
    } else throw e;
}

Prevention

When it happens

Trigger: A client registers a persistent instance (ephemeral=false) against a service that was created with ephemeral=true. The PersistentClientOperationServiceImpl resolves the singleton, finds it ephemeral, and rejects. This path is used for HTTP-based beat-style registration and explicit persistent gRPC registration.

Common situations: Service created as ephemeral (the default in many SDKs) but the client tries to register a persistent instance. Migration where the service type was changed but the client config was not updated. v1 HTTP API registration of a persistent instance against a v2 ephemeral service.

Related errors


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