OpenFeign/feign · error · IOException

Invalid uri

Error message

Invalid uri ${request.url()}

What it means

The synchronous java11 Http2Client builds a java.net.http.HttpRequest from the Feign Request's URL. If that URL cannot be parsed as a valid URI (URISyntaxException), it is rethrown as an IOException with the message 'Invalid uri <url>'. Feign templates can produce invalid URLs when unencoded special characters or spaces leak into the path or query.

Solutions

  1. Log request.url() from the wrapped IOException to see the offending URL
  2. Encode path/query values: use Util.encode or URLEncoder for user-supplied parameters
  3. Fix the @RequestLine / base URL (scheme://host syntax, no spaces)
  4. Percent-encode the target URL before building the client, or use a RequestInterceptor to sanitize URLs
  5. Verify no template placeholder ({param}) remains unexpanded

Example fix

// before
@RequestLine("GET /search?q={q}") Response search(@Param("q") String q);
api.search("hello world|foo");
// after
api.search(URLEncoder.encode("hello world|foo", StandardCharsets.UTF_8));
// or fix the request line: @RequestLine("GET /search?q={q}") with properly encoded params
Defensive patterns

Strategy: validation

Validate before calling

String url = request.url();
try {
  new java.net.URI(url); // throws URISyntaxException if invalid
} catch (URISyntaxException e) {
  throw new IllegalStateException("Request URL is not a valid URI: " + url, e);
}

Type guard

static boolean isValidUri(String s) {
  try { new java.net.URI(s); return true; } catch (URISyntaxException e) { return false; }
}

Try / catch

try {
  return client.execute(request, options);
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Invalid uri")) {
    throw new IllegalArgumentException("Fix request URL encoding: " + e.getMessage(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: execute() on Http2Client when Request.url() contains characters illegal in a URI - spaces, unencoded '|', '{', '}', non-ASCII characters, or a malformed host/scheme produced by a bad @RequestLine or unexpanded template values.

Common situations: Path/query parameters containing spaces or unicode without Encoding; building URLs manually with Target.EmptyTarget and bad base URLs; Feign version upgrades changing default encoding behavior; template placeholders left unsubstituted.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at java11/src/main/java/feign/http2client/Http2Client.java:100

            .connectTimeout(Duration.ofMillis(10000))
            .build());
  }

  public Http2Client(Options options) {
    this(newClientBuilder(options).version(Version.HTTP_2).build());
  }

  public Http2Client(HttpClient client) {
    this.client = Util.checkNotNull(client, "HttpClient must not be null");
  }

  @Override
  public Response execute(Request request, Options options) throws IOException {
    final HttpRequest httpRequest;
    try {
      httpRequest = newRequestBuilder(request, options).version(client.version()).build();
    } catch (URISyntaxException e) {
      throw new IOException("Invalid uri " + request.url(), e);
    }

    HttpClient clientForRequest = getOrCreateClient(options);
    HttpResponse<InputStream> httpResponse;
    try {
      httpResponse = clientForRequest.send(httpRequest, BodyHandlers.ofInputStream());
    } catch (final InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new IOException(e);
    }

    return toFeignResponse(request, httpResponse);
  }

  @Override
  public CompletableFuture<Response> execute(
      Request request, Options options, Optional<Object> requestContext) {
    HttpRequest httpRequest;

View on GitHub (pinned to e2a1e27560)