apache/shenyu · error · ShenyuAdminException

registry_id is already exist

Error message

registry_id is already exist

What it means

Thrown by the private RegistryServiceImpl.create() when a registry config with the same registryId already exists. create() looks up registryMapper.selectByRegistryId() and throws ShenyuAdminException("registry_id is already exist") to enforce registryId uniqueness, since createOrUpdate routes to create when no row id is supplied.

Solutions

  1. Query existing registries first; if the registryId exists, call createOrUpdate with the existing row's id so it takes the update path.
  2. Catch ShenyuAdminException and treat it as idempotent success if the registryId is the one you intended.
  3. Choose a different, unique registryId if you actually want a second registry entry.
  4. Delete the stale registry entry before re-creating it with the same id.

Example fix

// before
RegistryDTO dto = new RegistryDTO();
dto.setRegistryId("zk-registry"); // id left null -> insert path
registryService.createOrUpdate(dto);

// after
RegistryDO existing = registryMapper.selectByRegistryId("zk-registry");
RegistryDTO dto = new RegistryDTO();
dto.setRegistryId("zk-registry");
if (existing != null) {
    dto.setId(existing.getId()); // route to update path
}
registryService.createOrUpdate(dto);
Defensive patterns

Strategy: validation

Validate before calling

if (registryMapper.selectByRegistryId(dto.getRegistryId()) != null) {
    // route to update (set dto.id) or reject before calling createOrUpdate
}

Try / catch

try {
    registryService.createOrUpdate(dto);
} catch (ShenyuAdminException e) {
    if ("registry_id is already exist".equals(e.getMessage())) { /* fetch existing by registryId and update instead */ } else { throw e; }
}

Prevention

When it happens

Trigger: Calling createOrUpdate with a RegistryDTO whose id is null but whose registryId already exists in the registry table — i.e. an 'insert' that collides with an existing registry identifier.

Common situations: Registering the same registry (e.g. same zookeeper/nacos address id) twice through the dashboard or REST API; re-running an init/import script that already created the registry.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/c1b1d343c2fffebf. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/RegistryServiceImpl.java:89

        return RegistryTransfer.INSTANCE.mapToVo(registryMapper.selectById(id));
    }

    @Override
    public RegistryVO findByRegistryId(final String registryId) {
        return RegistryTransfer.INSTANCE.mapToVo(registryMapper.selectByRegistryId(registryId));
    }

    @Override
    public List<RegistryVO> listAll() {
        List<RegistryDO> registryDOS = registryMapper.selectAll();
        return registryDOS.stream().map(RegistryTransfer.INSTANCE::mapToVo).collect(Collectors.toList());
    }


    private RegistryVO create(final RegistryDTO registryDTO) {
        RegistryDO existRegistryDO = registryMapper.selectByRegistryId(registryDTO.getRegistryId());
        if (Objects.nonNull(existRegistryDO)) {
            throw new ShenyuAdminException("registry_id is already exist");
        }

        Timestamp currentTime = new Timestamp(System.currentTimeMillis());
        String id = UUIDUtils.getInstance().generateShortUuid();
        RegistryDO registryDO = RegistryDO.builder()
                .id(id)
                .registryId(registryDTO.getRegistryId())
                .protocol(registryDTO.getProtocol())
                .address(registryDTO.getAddress())
                .namespace(registryDTO.getNamespace())
                .username(registryDTO.getUsername())
                .password(registryDTO.getPassword())
                .registryGroup(registryDTO.getGroup())
                .dateCreated(currentTime)
                .dateUpdated(currentTime)
                .build();
        registryMapper.insert(registryDO);

View on GitHub (pinned to 567142e072)