{"record":{"id":"f8f7ee7ff272a0e2","repo":"apache/shenyu","slug":"doheartbeat-failed-to-execute-wait-to-retry","errorCode":null,"errorMessage":"doHeartbeat Failed to execute,wait to retry.","messagePattern":"doHeartbeat Failed to execute,wait to retry\\.","errorType":"exception","errorClass":"ShenyuException","httpStatus":null,"severity":"warning","filePath":"shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractShenyuClientRegisterServiceImpl.java","lineNumber":247,"sourceCode":"        PluginDO pluginDO = pluginMapper.selectByName(pluginName);\n        if (Objects.isNull(pluginDO)) {\n            throw new IllegalArgumentException(errorMsg);\n        }\n        NamespacePluginVO namespacePluginRelation = namespacePluginRelMapper.selectByPluginIdAndNamespaceId(pluginDO.getId(), namespaceId);\n        if (Objects.isNull(namespacePluginRelation)) {\n            throw new IllegalArgumentException(errorMsg);\n        }\n    }\n    \n    @Override\n    public String doHeartbeat(final String selectorName, final List<URIRegisterDTO> uriList, final String namespaceId) {\n        if (CollectionUtils.isEmpty(uriList)) {\n            return \"\";\n        }\n        String pluginName = PluginNameAdapter.rpcTypeAdapter(rpcType());\n        SelectorDO selectorDO = selectorService.findByNameAndPluginNameAndNamespaceId(selectorName, pluginName, namespaceId);\n        if (Objects.isNull(selectorDO)) {\n            throw new ShenyuException(\"doHeartbeat Failed to execute,wait to retry.\");\n        }\n        // update upstream\n        List<URIRegisterDTO> validUriList = uriList.stream().filter(dto -> Objects.nonNull(dto.getPort()) && StringUtils.isNotBlank(dto.getHost())).toList();\n        if (CollectionUtils.isEmpty(validUriList)) {\n            return null;\n        }\n        // discovery publish change event.\n        String selectorId = selectorDO.getId();\n        // change live node status to TRUE\n        validUriList.forEach(uriRegisterDTO -> {\n            DiscoveryUpstreamDTO discoveryUpstreamDTO = CommonUpstreamUtils.buildDefaultDiscoveryUpstreamDTO(uriRegisterDTO.getHost(),\n                    uriRegisterDTO.getPort(),\n                    uriRegisterDTO.getProtocol(),\n                    uriRegisterDTO.getNamespaceId());\n\n            try {\n                // publish instance info event\n                InstanceInfoReportEvent instanceInfoReportEvent = new InstanceInfoReportEvent(","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractShenyuClientRegisterServiceImpl.java#L229-L265","documentation":"doHeartbeat() throws ShenyuException when no SelectorDO exists for selectorName + pluginName + namespaceId, meaning a heartbeat arrived for a selector the admin does not know. Like doRegisterURI, the 'wait to retry' wording indicates an expected eventual-consistency race: heartbeats are usually retried by the client until the selector appears.","triggerScenarios":"Client sends periodic heartbeats for a selectorName that is absent in the DB for that namespace/plugin — heartbeat scheduled before the initial metadata/selector registration completed, or selector deleted in the dashboard while the client is still running.","commonSituations":"Client restarted before admin registered its metadata; heartbeat timer faster than registration; namespaceId mismatch; an operator removed the selector but left the backend service running and heartbeating.","solutions":["Let the client retry — Shenyu client registration retries heartbeats until the selector exists.","Ensure metadata registration (selector creation) succeeds before/independent of heartbeat scheduling.","Recreate the selector in the dashboard if it was deleted intentionally while the service is still up.","Check namespaceId consistency between the client config and the selector's namespace."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"SelectorDO selector = selectorService.findByNameAndPluginNameAndNamespaceId(selectorName, pluginName, namespaceId);\nif (selector == null) {\n    // delay heartbeat until metadata registration has created the selector\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    registerService.doHeartbeat(selectorName, uriList, namespaceId);\n} catch (ShenyuException e) {\n    if (e.getMessage().contains(\"doHeartbeat Failed\")) {\n        scheduler.schedule(() -> doHeartbeatWithRetry(selectorName, uriList, namespaceId), 5, SECONDS);\n    } else { throw e; }\n}","preventionTips":["Schedule heartbeats only after the initial registration reports success.","Use exponential backoff for heartbeat retries so logs aren't flooded during startup races.","Keep namespaceId consistent across metadata and heartbeat calls.","Recreate or re-register selectors if deleted while backend instances are live."],"tags":["heartbeat","selector","retry","race-condition"],"backgroundTag":"entity-not-found","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}