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

  1. Verify the selector exists in the dashboard for the exact pluginName, selectorName and namespaceId sent in the DTO.
  2. Ensure the client registers/creates the selector before or together with the discovery config, and correct namespaceId.
  3. Check client configuration (plugin name, namespace) matches the server-side selector.
  4. 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

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


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)