OpenFeign/feign · error · UnsupportedOperationException

Empty targets don't have URLs

Error message

Empty targets don't have URLs

What it means

Target.EmptyTarget represents a target without a URL (used when only the name matters, e.g. with load balancers or RequestInterceptors supplying the host). Calling url() on it is unsupported by design because no URL exists. This exception is thrown unconditionally.

Solutions

  1. Use Target.name() instead of url() for EmptyTarget identification
  2. Guard with `instanceof Target.EmptyTarget` before calling url()
  3. Provide a real Target (HardCodedTarget with URL) if your code needs a URL
  4. Use Feign's request pipeline (apply) rather than reading the URL directly

Example fix

// before
String url = target.url(); // throws for EmptyTarget
// after
String url = target instanceof Target.EmptyTarget ? null : target.url();
Defensive patterns

Strategy: type-guard

Validate before calling

boolean hasUrl = !(target instanceof Target.EmptyTarget);

Type guard

String urlOf(Target t) { return t instanceof Target.EmptyTarget ? null : t.url(); }

Try / catch

try { url = target.url(); } catch (UnsupportedOperationException e) { url = null; }

Prevention

When it happens

Trigger: Calling Target.url() on an instance obtained via Target.EmptyTarget.create(Class) or create(Class, String); typically in code that generically inspects targets of any kind.

Common situations: Generic tooling/logging that iterates over Target objects assuming a concrete URL; code that swaps HardCodedTarget for EmptyTarget without updating URL accessors.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10). Data as JSON: /api/errors/ac8ce5c8aff7c1ae. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/feign/Target.java:169

    }

    public static <T> EmptyTarget<T> create(Class<T> type, String name) {
      return new EmptyTarget<T>(type, name);
    }

    @Override
    public Class<T> type() {
      return type;
    }

    @Override
    public String name() {
      return name;
    }

    @Override
    public String url() {
      throw new UnsupportedOperationException("Empty targets don't have URLs");
    }

    @Override
    public Request apply(RequestTemplate input) {
      if (input.url().indexOf("http") != 0) {
        throw new UnsupportedOperationException(
            "Request with non-absolute URL not supported with empty target");
      }
      return input.request();
    }

    @Override
    public boolean equals(Object obj) {
      if (obj instanceof EmptyTarget) {
        EmptyTarget<?> other = (EmptyTarget) obj;
        return type.equals(other.type) && name.equals(other.name);
      }
      return false;

View on GitHub (pinned to e2a1e27560)