apache/shenyu · error · ShenyuException

The configuration shenyu.discovery.type in xml/yml cannot…

Error message

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

What it means

ClientDiscoveryConfigRefreshedEventListener builds the discovery registration DTO from the `shenyu.discovery.*` client config. When building, it validates that shenyu.discovery.type is non-empty because the discovery SPI implementation is chosen by type; a blank type means no discovery implementation can be selected, so a ShenyuException is thrown and client registration aborts.

Solutions

  1. Add the discovery type to your client config, e.g. `shenyu: discovery: type: zookeeper` (or nacos/etcd/consul), matching a ShenyuDiscoveryService SPI implementation on the classpath.
  2. Verify the property is not overridden to empty by an active Spring profile or environment variable.
  3. Check startup logs for the paired error `shenyu.discovery.serverList ... cannot be null` and fill serverList too, then set type.
  4. Confirm the corresponding discovery client dependency/starter is present so the chosen type has an implementation.

Example fix

# before
shenyu:
  discovery:
    serverList: localhost:2181
# after
shenyu:
  discovery:
    type: zookeeper
    serverList: localhost:2181
Defensive patterns

Strategy: validation

Validate before calling

// Spring boot startup check
@PostConstruct
void checkDiscoveryConfig() {
    ShenyuClientConfig.DiscoveryConfig d = shenyuClientConfig.getDiscovery();
    if (d == null || d.getType() == null || d.getType().isEmpty()) {
        throw new IllegalStateException("shenyu.discovery.type must be set (e.g. zookeeper, nacos)");
    }
    if (d.getServerList() == null || d.getServerList().isEmpty()) {
        throw new IllegalStateException("shenyu.discovery.serverList must be set");
    }
}

Type guard

boolean hasText(String s) { return s != null && !s.trim().isEmpty(); }

Prevention

When it happens

Trigger: A Shenyu client app (spring-mvc/spring-cloud etc.) enables service discovery but its yml/properties omits `shenyu.discovery.type` or sets it to an empty string; the listener fires on a config-refresh/ApplicationReady event and calls buildDiscoveryConfigRegisterDTO, which throws immediately after the serverList check passes.

Common situations: Copy-pasted client config that includes serverList but forgot the type field; renaming config keys across versions (e.g. migrating from `shenyu.register` props to `shenyu.discovery`); using a profile that overrides shenyu.discovery and drops type.

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/29ff270bbd6ede22. Report an issue: GitHub.

Appendix: source

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

    @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();
    }

    private String discoveryName() {
        return "default_" + shenyuDiscoveryConfig.getType();
    }

View on GitHub (pinned to 567142e072)