apache/shenyu · error · ShenyuException
when binding discovery don't find selector
Error message
when binding discovery don't find selector %s
What it means
DiscoveryServiceImpl.findAndLockOnDB() looks up a selector by name+plugin+namespace with a SELECT ... FOR UPDATE, retrying up to 3 times with 500ms sleeps (to tolerate registration race windows). If the selector is still absent after 3 attempts, it throws ShenyuException "when binding discovery don't find selector <name>". This guards registerDiscoveryConfig, which binds a discovery config to an existing selector.
Solutions
- Verify the selector exists in the dashboard for the exact pluginName, selectorName and namespaceId sent in the DTO.
- Ensure the client registers/creates the selector before or together with the discovery config, and correct namespaceId.
- Check client configuration (plugin name, namespace) matches the server-side selector.
- Server-side: increase retries/backoff in findAndLockOnDB if this is a transient registration-order race.
Example fix
// before // client registers discovery with selectorName "my-service" but selector was never created // after // 1. create selector "my-service" for pluginName (e.g. "divide") in the correct namespace // 2. then send DiscoveryConfigRegisterDTO with matching selectorName/pluginName/namespaceId
Defensive patterns
Strategy: retry
Validate before calling
// before registering discovery config, confirm the selector exists
SelectorDO selector = selectorService.findByNameAndPluginNameAndNamespaceId(
dto.getSelectorName(), dto.getPluginName(), namespaceId);
if (selector == null) {
throw new IllegalStateException("selector " + dto.getSelectorName() + " not found; create it first");
}
registerService.registerDiscoveryConfig(dto); Try / catch
try {
discoveryService.registerDiscoveryConfig(dto);
} catch (ShenyuException e) {
if (e.getMessage().startsWith("when binding discovery don't find selector")) {
// selector missing: create selector then retry registration
}
throw e;
} Prevention
- Register the selector before publishing discovery config from client SDKs.
- Double-check pluginName, selectorName and namespaceId in client config match the dashboard values.
- After namespace migration, re-sync client namespace settings.
- If racy, retry registration with backoff on the client side.
When it happens
Trigger: A client (typically a ShenYu client SDK registering discovery config) sends a DiscoveryConfigRegisterDTO whose selectorName+pluginName+namespaceId do not match any existing selector row — selector not yet created, wrong plugin name, wrong namespaceId, or a typo in the selector name.
Common situations: Client registers discovery before its selector/URI registration completes and exceeds the 3-retry (~1.5s) window; namespace mismatch after upgrading to multi-namespace ShenYu; selector created under a different plugin name; selector deleted concurrently.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- namespace is not exist
- before start ProxySelector you need init DiscoveryId=
- before start ProxySelector you need init DiscoveryId=
- shenyu discovery start watcher need you has this key
- shenyu discovery mode current didn't support
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/3b78e40569486daa.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryServiceImpl.java:141
SelectorDO selectorDO = findAndLockOnDB(discoveryConfigRegisterDTO.getSelectorName(), discoveryConfigRegisterDTO.getPluginName(), discoveryConfigRegisterDTO.getNamespaceId());
bindingDiscovery(discoveryConfigRegisterDTO, selectorDO);
}
private SelectorDO findAndLockOnDB(final String selectorName, final String pluginName, final String namespaceId) {
SelectorDO selectorDO = null;
for (int i = 0; i < 3; i++) {
selectorDO = selectorService.findByNameAndPluginNameAndNamespaceIdForUpdate(selectorName, pluginName, namespaceId);
if (Objects.nonNull(selectorDO)) {
return selectorDO;
}
try {
LOG.info("retry to find selector {} : {}", selectorName, pluginName);
Thread.sleep(500);
} catch (InterruptedException e) {
// ignore
}
}
throw new ShenyuException("when binding discovery don't find selector " + selectorName);
}
private void bindingDiscovery(final DiscoveryConfigRegisterDTO discoveryConfigRegisterDTO, final SelectorDO selectorDO) {
ProxySelectorDTO proxySelectorDTO = new ProxySelectorDTO();
proxySelectorDTO.setName(selectorDO.getSelectorName());
proxySelectorDTO.setId(selectorDO.getId());
proxySelectorDTO.setPluginName(discoveryConfigRegisterDTO.getPluginName());
proxySelectorDTO.setNamespaceId(selectorDO.getNamespaceId());
DiscoveryDO discoveryDO = discoveryMapper.selectByPluginNameAndLevelAndNamespaceIdAndType(discoveryConfigRegisterDTO.getPluginName(),
DiscoveryLevel.PLUGIN.getCode(), discoveryConfigRegisterDTO.getNamespaceId(), discoveryConfigRegisterDTO.getDiscoveryType());
if (Objects.isNull(discoveryDO)) {
Timestamp currentTime = new Timestamp(System.currentTimeMillis());
discoveryDO = DiscoveryDO.builder()
.id(UUIDUtils.getInstance().generateShortUuid())
.discoveryName(discoveryConfigRegisterDTO.getName())
.pluginName(discoveryConfigRegisterDTO.getPluginName())
.discoveryType(discoveryConfigRegisterDTO.getDiscoveryType())
.discoveryLevel(DiscoveryLevel.PLUGIN.getCode())View on GitHub (pinned to 567142e072)