OpenFeign/feign · error · UnsupportedOperationException
Options should be provided directly during construction of…
Error message
Options should be provided directly during construction of Vertx WebClient.
What it means
VertxFeign's builder overrides Feign.Builder.options() to reject per-builder Request.Options because with a reactive Vertx WebClient, timeouts/connect options must be configured on the WebClient itself at construction time. Calling options(...) throws UnsupportedOperationException with guidance to configure options directly on the WebClient.
Solutions
- Remove the .options(...) call and instead configure timeouts/connect options on the WebClient (e.g. WebClientOptions with connectTimeout/readTimeout/idleTimeout) passed to VertxFeign.builder().
- If using HttpClientOptions/RequestOptions, set them when creating the WebClient so every Feign request inherits them.
- Centralize the settings in WebClient creation code rather than the Feign builder to avoid the exception path entirely.
Example fix
// before
VertxFeign.builder().options(new Request.Options(10, 60_000)).target(Api.class, url);
// after
WebClient client = WebClient.create(vertx,
new WebClientOptions().setConnectTimeout(10_000).setIdleTimeout(60));
VertxFeign.builder().webClient(client).target(Api.class, url); Defensive patterns
Strategy: validation
Validate before calling
// Configure on WebClient, never call .options on VertxFeign builder
WebClientOptions opts = new WebClientOptions()
.setConnectTimeout(10_000)
.setIdleTimeout(60);
WebClient webClient = WebClient.create(vertx, opts);
java.util.Objects.requireNonNull(webClient, "WebClient with options required for VertxFeign"); Try / catch
try {
builder.options(new Request.Options(10, 60_000));
} catch (UnsupportedOperationException e) {
if (e.getMessage() != null && e.getMessage().contains("Options should be provided directly")) {
// move options into WebClientOptions and rebuild WebClient
}
throw e;
} Prevention
- Never copy plain-Feign .options(...) calls into VertxFeign builders.
- Set all timeouts in WebClientOptions at WebClient construction.
- Keep a shared factory function that builds the configured WebClient for all VertxFeign clients.
When it happens
Trigger: Calling .options(new Request.Options(...)) on a VertxFeign builder (obtained via VertxFeign.builder() / its Feign.Builder view) before target(), e.g. code ported from standard Feign configuration that sets timeouts via the builder.
Common situations: Migrating a plain Feign client setup to VertxFeign and copying the .options(...) line; central Feign configuration helpers that always call options(); attempting to raise read timeouts for slow endpoints in a Vertx setup.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Status Code [ ] has already been declared to throw [ ] and…
- target values must be absolute.
- Target is not a valid URI.
- Empty targets don't have URLs
- Unable to decode response ( ) ...
AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10).
Data as JSON: /api/errors/caba7b40a8f4dbe8.
Report an issue: GitHub.
Appendix: source
Thrown at vertx/feign-vertx/src/main/java/feign/VertxFeign.java:367
return target(new Target.HardCodedTarget<>(apiType, url));
}
/**
* Defines target and builds client.
*
* @param target target instance
* @param <T> class of API interface
* @return built client
*/
@Override
public <T> T target(final Target<T> target) {
return build().newInstance(target);
}
@Override
public Feign.Builder options(final Request.Options options) {
throw new UnsupportedOperationException(
"Options should be provided directly during construction of Vertx WebClient.");
}
@Override
public VertxFeign internalBuild() {
checkNotNull(
this.webClient, "Vertx WebClient instance wasn't provided in VertxFeign builder");
final VertxHttpClient client = new VertxHttpClient(webClient, timeout, requestPreProcessor);
final VertxMethodHandler.Factory methodHandlerFactory =
new VertxMethodHandler.Factory(
client, retryer, requestInterceptors, logger, logLevel, decode404);
final ParseHandlersByName handlersByName =
new ParseHandlersByName(
contract,
encoder,
decoder,
queryMapEncoder,View on GitHub (pinned to e2a1e27560)