apache/shenyu · error · IllegalStateException

Either 'name' or 'value' must be provided in @FeignClient

Error message

Either 'name' or 'value' must be provided in @FeignClient

What it means

getClientName() derives the logical service name for a @FeignClient-annotated interface. It checks name, then value, then serviceId attributes; if none contains text it throws IllegalStateException because the SDK cannot register or route the client without a name. The annotation contract requires at least one of these attributes.

Solutions

  1. Add a name to the annotation: @FeignClient(name = "order-service").
  2. Alternatively set value or serviceId to a non-empty string — getClientName accepts any of the three.
  3. If the name should come from configuration, use @FeignClient(name = "${client.order.name}") and define that property.
  4. Audit all @FeignClient interfaces at startup (e.g. a unit test scanning the package) to catch missing names early.

Example fix

// before
@FeignClient(url = "http://localhost:9195")
public interface OrderApi { }
// after
@FeignClient(name = "order-service", url = "http://localhost:9195")
public interface OrderApi { }
Defensive patterns

Strategy: validation

Validate before calling

FeignClient a = clazz.getAnnotation(FeignClient.class);
boolean named = a != null && Stream.of(a.name(), a.value(), a.serviceId()).anyMatch(StringUtils::hasText);
if (!named) throw new IllegalStateException("@FeignClient on " + clazz.getName() + " needs name/value/serviceId");

Prevention

When it happens

Trigger: Declaring @FeignClient (or Shenyu's equivalent) with no name/value/serviceId, or with only an empty string, e.g. @FeignClient(url = "http://localhost:9195") or @FeignClient("").

Common situations: Copy-pasting an interface and deleting the name attribute; specifying only contextId or url and assuming name is optional; refactoring that moved the name to a constant which was left blank.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at shenyu-sdk/shenyu-sdk-feign/src/main/java/org/apache/shenyu/sdk/feign/ShenyuClientsRegistrar.java:462

    private String getClientName(final Map<String, Object> client) {
        if (Objects.isNull(client)) {
            return null;
        }
        String value = (String) client.get("contextId");
        if (!StringUtils.hasText(value)) {
            value = (String) client.get("value");
        }
        if (!StringUtils.hasText(value)) {
            value = (String) client.get("name");
        }
        if (!StringUtils.hasText(value)) {
            value = (String) client.get("serviceId");
        }
        if (StringUtils.hasText(value)) {
            return value;
        }

        throw new IllegalStateException(
            "Either 'name' or 'value' must be provided in @" + FeignClient.class.getSimpleName());
    }

    private void registerClientConfiguration(final BeanDefinitionRegistry registry, final Object name, final Object configuration) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(FeignClientSpecification.class);
        builder.addConstructorArgValue(name);
        builder.addConstructorArgValue(configuration);
        registry.registerBeanDefinition(name + "." + FeignClientSpecification.class.getSimpleName(),
            builder.getBeanDefinition());
    }

    private boolean isClientRefreshEnabled() {
        return environment.getProperty("feign.client.refresh-enabled", Boolean.class, false);
    }

}

View on GitHub (pinned to 567142e072)