{"record":{"id":"3cc21e13734c9e67","repo":"apache/shenyu","slug":"the-configuration-shenyu-discovery-serverlist-in-xml-yml","errorCode":null,"errorMessage":"The configuration shenyu.discovery.serverList in xml/yml cannot be null","messagePattern":"The configuration shenyu\\.discovery\\.serverList in xml/yml cannot be null","errorType":"exception","errorClass":"ShenyuException","httpStatus":null,"severity":"error","filePath":"shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientDiscoveryConfigRefreshedEventListener.java","lineNumber":84,"sourceCode":"            namespace = Constants.SYS_DEFAULT_NAMESPACE_ID;\n        }\n        this.namespace = Lists.newArrayList(StringUtils.split(namespace, Constants.SEPARATOR_CHARS));\n    }\n\n    @Override\n    public void onApplicationEvent(final ContextRefreshedEvent event) {\n        List<String> namespaceIds = this.getNamespace();\n        namespaceIds.forEach(namespaceId -> {\n            DiscoveryConfigRegisterDTO discoveryConfigRegisterDTO = buildDiscoveryConfigRegisterDTO(shenyuDiscoveryConfig, namespaceId);\n            httpClientRegisterRepository.doPersistDiscoveryConfig(discoveryConfigRegisterDTO);\n        });\n\n    }\n\n    protected DiscoveryConfigRegisterDTO buildDiscoveryConfigRegisterDTO(final ShenyuDiscoveryConfig shenyuDiscoveryConfig, final String namespaceId) {\n        if (StringUtils.isEmpty(shenyuDiscoveryConfig.getServerList())) {\n            LOG.error(\"If using service discovery. The configuration shenyu.discovery.name in xml/yml cannot be null\");\n            throw new ShenyuException(\"The configuration shenyu.discovery.serverList in xml/yml cannot be null\");\n        }\n        if (StringUtils.isEmpty(shenyuDiscoveryConfig.getType())) {\n            LOG.error(\"If using service discovery. The configuration shenyu.discovery.name in xml/yml cannot be null\");\n            throw new ShenyuException(\"The configuration shenyu.discovery.type in xml/yml cannot be null\");\n        }\n        return DiscoveryConfigRegisterDTO.builder()\n                .name(discoveryName())\n                .selectorName(clientRegisterConfig.getContextPath())\n                .handler(\"{}\")\n                .listenerNode(shenyuDiscoveryConfig.getRegisterPath())\n                .serverList(shenyuDiscoveryConfig.getServerList())\n                .props(shenyuDiscoveryConfig.getProps())\n                .discoveryType(shenyuDiscoveryConfig.getType())\n                .pluginName(plugin.getName())\n                .namespaceId(namespaceId)\n                .build();\n    }\n","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientDiscoveryConfigRefreshedEventListener.java#L66-L102","documentation":"buildDiscoveryConfigRegisterDTO validates that a ShenyuDiscoveryConfig has a non-empty serverList before registering the discovery config with admin; if empty it throws ShenyuException. Service discovery registration (zookeeper/nacos etc. for proxy backends) cannot proceed without the server list.","triggerScenarios":"ClientDiscoveryConfigRefreshedEventListener.discoveryConfigRegisterDTO processing a shenyu.discovery config block whose serverList property is null or empty in xml/yml.","commonSituations":"Configuring shenyu.discovery (name, type) but forgetting serverList; renaming the key (e.g. server-list vs serverList); YAML nesting putting serverList in the wrong place; environment-specific configs where the discovery block was partially copied.","solutions":["Set shenyu.discovery.serverList (comma-separated addresses of the registry, e.g. localhost:2181) in your yml","Verify the key name and nesting match the current ShenYu schema for discovery config","Ensure the active Spring profile's config includes serverList if profiles override the discovery block","Add a type too — the same method throws next for a missing discovery type"],"exampleFix":"// before\nshenyu:\n  discovery:\n    name: zk\n    type: zookeeper\n// after\nshenyu:\n  discovery:\n    name: zk\n    type: zookeeper\n    serverList: 127.0.0.1:2181","handlingStrategy":"validation","validationCode":"// before enabling discovery registration, validate config\nString serverList = /* shenyu.discovery.serverList */;\nif (serverList == null || serverList.isBlank()) {\n    throw new IllegalStateException(\"shenyu.discovery.serverList must be set\");\n}\nString type = /* shenyu.discovery.type */;\nif (type == null || type.isBlank()) {\n    throw new IllegalStateException(\"shenyu.discovery.type must be set\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    discoveryListener.register(dto);\n} catch (ShenyuException e) {\n    log.error(\"Discovery registration failed: {}\", e.getMessage());\n    // fix serverList/type in yml and restart\n}","preventionTips":["Always provide serverList and type together when configuring shenyu.discovery","Validate discovery config across all active Spring profiles","Verify address format of serverList entries (host:port, comma-separated)"],"tags":["configuration","discovery","client","validation"],"backgroundTag":"missing-required-config-field","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"}