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
- Query existing registries first; if the registryId exists, call createOrUpdate with the existing row's id so it takes the update path.
- Catch ShenyuAdminException and treat it as idempotent success if the registryId is the one you intended.
- Choose a different, unique registryId if you actually want a second registry entry.
- 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
- Always look up the registry by registryId before insert.
- Reuse the existing row's id to take the update path for idempotent upserts.
- Use unique, descriptive registryIds per environment.
- Make import scripts re-runnable by checking existence first.
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
- The user namespace rel is exist!
- unique index conflict, please enter again
- registry is not exist
- uri validation of Condition failed, please check.
- parameter error
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)