quarkusio/quarkus · error · RuntimeException
Can't call `update` method in a Reactive context. Use `getHe
Error message
Can't call `update` method in a Reactive context. Use `getHeaders` or implement ClientHeadersFactory.
What it means
`ReactiveClientHeadersFactory` implements the blocking `ClientHeadersFactory.update` API but is designed for reactive usage via `getHeaders` returning a Uni. Calling `update` (which the framework does only if the factory is misused as a blocking factory) always throws, directing the developer to override `getHeaders` instead.
Source
Thrown at extensions/resteasy-reactive/rest-client/runtime/src/main/java/io/quarkus/rest/client/reactive/ReactiveClientHeadersFactory.java:31
/**
* Updates the HTTP headers to send to the remote service. Note that providers
* on the outbound processing chain could further update the headers.
*
* @param incomingHeaders the map of headers from the inbound JAX-RS request. This will be an empty map if the
* associated client interface is not part of a JAX-RS request.
* @param clientOutgoingHeaders the read-only map of header parameters specified on the client interface.
* @return a Uni with a map of HTTP headers to merge with the clientOutgoingHeaders to be sent to the remote service.
*
* @see ClientHeadersFactory#update(MultivaluedMap, MultivaluedMap)
*/
public abstract Uni<MultivaluedMap<String, String>> getHeaders(MultivaluedMap<String, String> incomingHeaders,
MultivaluedMap<String, String> clientOutgoingHeaders);
@Override
public final MultivaluedMap<String, String> update(MultivaluedMap<String, String> incomingHeaders,
MultivaluedMap<String, String> clientOutgoingHeaders) {
throw new RuntimeException(
"Can't call `update` method in a Reactive context. Use `getHeaders` or implement ClientHeadersFactory.");
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Override `getHeaders(MultivaluedMap, MultivaluedMap)` and put the header logic there returning `Uni.createFrom().item(...)`
- Ensure the factory is registered as a reactive headers factory (e.g. via @RegisterClientHeadersFactory pointing at the reactive type)
- If blocking logic is needed, extend plain ClientHeadersFactory instead and implement update()
Example fix
// before
public class MyFactory extends ReactiveClientHeadersFactory {
public MultivaluedMap<String,String> update(...) { ... }
}
// after
public class MyFactory extends ReactiveClientHeadersFactory {
@Override
public Uni<MultivaluedMap<String,String>> getHeaders(MultivaluedMap<String,String> in, MultivaluedMap<String,String> out) {
in.add("Authorization", "Bearer x");
return Uni.createFrom().item(in);
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure subclasses override getHeaders, not update
for (Class<?> c : List.of(MyHeadersFactory.class)) {
if (ReactiveClientHeadersFactory.class.isAssignableFrom(c)
&& !Arrays.stream(c.getDeclaredMethods())
.anyMatch(m -> m.getName().equals("getHeaders") && !m.isSynthetic())) {
throw new IllegalStateException(c + " must override getHeaders");
}
} Try / catch
try {
factory.update(incoming, outgoing);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Use `getHeaders`")) {
throw new AssertionError("Wrong factory type: use ReactiveClientHeadersFactory.getHeaders", e);
}
throw e;
} Prevention
- Always override getHeaders when extending ReactiveClientHeadersFactory
- Never call update() directly on reactive factories, including in tests
- Use plain ClientHeadersFactory if synchronous behavior is required
When it happens
Trigger: Implementing a class extending ReactiveClientHeadersFactory but having it registered where the synchronous ClientHeadersFactory.update path is invoked, or calling update() directly in code/tests.
Common situations: Switching an existing ClientHeadersFactory to extend ReactiveClientHeadersFactory without realizing the entry point changed; invoking update() in a unit test.
Related errors
- Specifying executor service is not supported. The underlying
- When using Multi as body parameter only Multi<io.vertx.core.
- Can only be called at runtime
- Failed to find any non-blocking provider for startup actions
- Stateless operations not supported
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/3a80776e864f5e02.
Report an issue: GitHub.