OpenFeign/feign · error · IllegalStateException

RequestLine annotation didn't start with an HTTP verb on…

Error message

RequestLine annotation didn't start with an HTTP verb on method %s

What it means

Thrown from DefaultContract's RequestLine annotation processing when the @RequestLine value does not begin with a recognized HTTP verb (e.g., it starts with a path like "/items/{id}" instead of "GET /items/{id}"). The contract parses the verb from the first token of the annotation value, so any missing or malformed method prefix fails this guard during interface parsing at client creation time.

Solutions

  1. Format the annotation as 'VERB /path', e.g. @RequestLine("GET /items/{id}")
  2. Use a valid HTTP verb (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) as the first whitespace-delimited token
  3. If using a custom contract or non-standard verb, switch to a Contract implementation that supports it or implement your own Contract
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at core/src/main/java/feign/DefaultContract.java:59 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at core/src/main/java/feign/DefaultContract.java:59

              "Headers annotation was empty on type %s.",
              data.configKey());
          final Map<String, Collection<String>> headers = toMap(headersOnType);
          headers.putAll(data.template().headers());
          data.template().headers(null); // to clear
          data.template().headers(headers);
        });
    super.registerMethodAnnotation(
        RequestLine.class,
        (ann, data) -> {
          final String requestLine = ann.value();
          checkState(
              emptyToNull(requestLine) != null,
              "RequestLine annotation was empty on method %s.",
              data.configKey());

          final Matcher requestLineMatcher = REQUEST_LINE_PATTERN.matcher(requestLine);
          if (!requestLineMatcher.find()) {
            throw new IllegalStateException(
                String.format(
                    "RequestLine annotation didn't start with an HTTP verb on method %s",
                    data.configKey()));
          } else {
            data.template().method(HttpMethod.valueOf(requestLineMatcher.group(1)));
            data.template().uri(requestLineMatcher.group(2));
          }
          data.template().decodeSlash(ann.decodeSlash());
          data.template().collectionFormat(ann.collectionFormat());
        });
    super.registerMethodAnnotation(
        Body.class,
        (ann, data) -> {
          final String body = ann.value();
          checkState(
              emptyToNull(body) != null,
              "Body annotation was empty on method %s.",
              data.configKey());

View on GitHub (pinned to e2a1e27560)