apache/shenyu · error · ShenyuException

doRegister Failed to execute, because selectorDO object is…

Error message

doRegister Failed to execute, because selectorDO object is null, wait to retry.

What it means

doRegisterURI() throws ShenyuException when no SelectorDO exists for the given selectorName + pluginName + namespaceId. URI registration requires an existing selector to attach URIs to; the code intentionally aborts with 'wait to retry' because the selector is usually created by a preceding metadata registration that has not completed or synced yet.

Solutions

  1. Ensure the client performs metadata registration (which creates the selector) before URI/heartbeat registration.
  2. Verify the client's namespaceId matches the namespace where the selector was created.
  3. Retry — the message explicitly says 'wait to retry'; the Shenyu client registration is designed to retry.
  4. Check the admin log line above the error ('selector info params: ...') to confirm which name/plugin/namespace was looked up and whether it exists in the selector table.
Defensive patterns

Strategy: retry

Validate before calling

// client-side, before registering URIs
SelectorDO selector = adminApi.findSelector(selectorName, pluginName, namespaceId);
if (selector == null) { registerMetaDataFirst(); /* creates the selector */ }

Try / catch

try {
    registerService.doRegisterURI(selectorName, uriList, namespaceId);
} catch (ShenyuException e) {
    if (e.getMessage().contains("selectorDO object is null")) {
        retryWithBackoff(() -> registerService.doRegisterURI(selectorName, uriList, namespaceId));
    } else { throw e; }
}

Prevention

When it happens

Trigger: A backend client registers URIs (doRegisterURI) before the selector with that name exists in the database for the target namespace — e.g. heartbeat/URI registration racing ahead of metadata registration, or a wrong namespaceId so the selector lookup misses.

Common situations: Client SDK starts and registers URIs immediately on boot before metadata registration finishes; namespaceId mismatch between client config and admin; selector was deleted in the dashboard while clients keep re-registering; eventual consistency gap between admin replicas.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractShenyuClientRegisterServiceImpl.java:204

    /**
     * Register uri string.
     *
     * @param selectorName the selector name
     * @param uriList      the uri list
     * @param namespaceId  the namespace id
     * @return the string
     */
    @Override
    public String doRegisterURI(final String selectorName, final List<URIRegisterDTO> uriList, final String namespaceId) {
        if (CollectionUtils.isEmpty(uriList)) {
            return "";
        }
        String pluginName = PluginNameAdapter.rpcTypeAdapter(rpcType());
        SelectorDO selectorDO = selectorService.findByNameAndPluginNameAndNamespaceId(selectorName, pluginName, namespaceId);
        LOG.info("selector info params: selectorName: {}, pluginName: {}, namespaceId: {}, selectorDO info: {}.",
                selectorName, pluginName, namespaceId, selectorDO);
        if (Objects.isNull(selectorDO)) {
            throw new ShenyuException("doRegister Failed to execute, because selectorDO object is null, wait to retry.");
        }
        this.checkNamespacePluginRel(namespaceId, pluginName);
        // fetch UPSTREAM_MAP data from db
        //upstreamCheckService.fetchUpstreamData();
        //update upstream
        List<URIRegisterDTO> validUriList = uriList.stream()
                .filter(dto -> Objects.nonNull(dto.getPort()) && StringUtils.isNotBlank(dto.getHost()))
                .collect(Collectors.toList());
        String handler = buildHandle(validUriList, selectorDO);
        if (Objects.nonNull(handler)) {
            selectorDO.setHandle(handler);
            SelectorData selectorData = selectorService.buildByNameAndPluginNameAndNamespaceId(selectorName, PluginNameAdapter.rpcTypeAdapter(rpcType()), namespaceId);
            selectorData.setHandle(handler);
            // update db
            selectorService.updateSelective(selectorDO);
            // publish change event.
            doDiscoveryLocal(selectorDO, pluginName, validUriList);
        }

View on GitHub (pinned to 567142e072)