apache/shenyu · error · ShenyuException

The configuration shenyu.discovery.serverList in xml/yml…

Error message

The configuration shenyu.discovery.serverList in xml/yml cannot be null

What it means

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.

Solutions

  1. Set shenyu.discovery.serverList (comma-separated addresses of the registry, e.g. localhost:2181) in your yml
  2. Verify the key name and nesting match the current ShenYu schema for discovery config
  3. Ensure the active Spring profile's config includes serverList if profiles override the discovery block
  4. Add a type too — the same method throws next for a missing discovery type

Example fix

// before
shenyu:
  discovery:
    name: zk
    type: zookeeper
// after
shenyu:
  discovery:
    name: zk
    type: zookeeper
    serverList: 127.0.0.1:2181
Defensive patterns

Strategy: validation

Validate before calling

// before enabling discovery registration, validate config
String serverList = /* shenyu.discovery.serverList */;
if (serverList == null || serverList.isBlank()) {
    throw new IllegalStateException("shenyu.discovery.serverList must be set");
}
String type = /* shenyu.discovery.type */;
if (type == null || type.isBlank()) {
    throw new IllegalStateException("shenyu.discovery.type must be set");
}

Try / catch

try {
    discoveryListener.register(dto);
} catch (ShenyuException e) {
    log.error("Discovery registration failed: {}", e.getMessage());
    // fix serverList/type in yml and restart
}

Prevention

When it happens

Trigger: ClientDiscoveryConfigRefreshedEventListener.discoveryConfigRegisterDTO processing a shenyu.discovery config block whose serverList property is null or empty in xml/yml.

Common situations: 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.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ClientDiscoveryConfigRefreshedEventListener.java:84

            namespace = Constants.SYS_DEFAULT_NAMESPACE_ID;
        }
        this.namespace = Lists.newArrayList(StringUtils.split(namespace, Constants.SEPARATOR_CHARS));
    }

    @Override
    public void onApplicationEvent(final ContextRefreshedEvent event) {
        List<String> namespaceIds = this.getNamespace();
        namespaceIds.forEach(namespaceId -> {
            DiscoveryConfigRegisterDTO discoveryConfigRegisterDTO = buildDiscoveryConfigRegisterDTO(shenyuDiscoveryConfig, namespaceId);
            httpClientRegisterRepository.doPersistDiscoveryConfig(discoveryConfigRegisterDTO);
        });

    }

    protected DiscoveryConfigRegisterDTO buildDiscoveryConfigRegisterDTO(final ShenyuDiscoveryConfig shenyuDiscoveryConfig, final String namespaceId) {
        if (StringUtils.isEmpty(shenyuDiscoveryConfig.getServerList())) {
            LOG.error("If using service discovery. The configuration shenyu.discovery.name in xml/yml cannot be null");
            throw new ShenyuException("The configuration shenyu.discovery.serverList in xml/yml cannot be null");
        }
        if (StringUtils.isEmpty(shenyuDiscoveryConfig.getType())) {
            LOG.error("If using service discovery. The configuration shenyu.discovery.name in xml/yml cannot be null");
            throw new ShenyuException("The configuration shenyu.discovery.type in xml/yml cannot be null");
        }
        return DiscoveryConfigRegisterDTO.builder()
                .name(discoveryName())
                .selectorName(clientRegisterConfig.getContextPath())
                .handler("{}")
                .listenerNode(shenyuDiscoveryConfig.getRegisterPath())
                .serverList(shenyuDiscoveryConfig.getServerList())
                .props(shenyuDiscoveryConfig.getProps())
                .discoveryType(shenyuDiscoveryConfig.getType())
                .pluginName(plugin.getName())
                .namespaceId(namespaceId)
                .build();
    }

View on GitHub (pinned to 567142e072)