OpenFeign/feign · error · IllegalArgumentException

Streams are not supported when using Reactive Wrappers

Error message

Streams are not supported when using Reactive Wrappers

What it means

If the type contained in the Publisher is (or extends) java.util.stream.Stream, the contract rejects it with IllegalArgumentException. Streams are one-shot, non-replayable lazy sequences and cannot be reliably materialized across reactive publishers/decoders, so the reactive module forbids them as element types.

Solutions

  1. Change the contained element type to a concrete collection or entity, e.g. Flux<List<T>> or Flux<T> instead of Flux<Stream<T>>
  2. Collect the stream into a List before returning, or model the data as a POJO
  3. If you need true streaming, use a different Feign module (e.g. the streaming/async decoding support of a specific client) instead of the reactive wrapper

Example fix

// before
Flux<Stream<User>> users();
// after
Flux<User> users();
Defensive patterns

Strategy: validation

Validate before calling

// reject Stream inside Publisher return types before building the target
if (Flux.class.isAssignableFrom(raw)) {
  Class<?> inner = Types.getRawType(((ParameterizedType) type).getActualTypeArguments()[0]);
  if (java.util.stream.Stream.class.isAssignableFrom(inner))
    throw new IllegalStateException("Do not use Stream inside reactive return types");
}

Type guard

static boolean isStreamInside(Type publisherType) {
  return publisherType instanceof ParameterizedType
      && java.util.stream.Stream.class.isAssignableFrom(
          feign.Types.getRawType(((ParameterizedType) publisherType).getActualTypeArguments()[0]));
}

Prevention

When it happens

Trigger: Declaring a method that returns Publisher<Stream<T>> (e.g. Flux<Stream<T>> or Mono<Stream<T>>) in a Feign interface used with ReactiveDelegatingContract.

Common situations: Mapping decoding code from streaming HTTP clients to reactive ones; interfaces where an entity already exposes a stream API; confusion between streaming decoding (unsupported here) and reactive publishers.

Related errors


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

Appendix: source

Thrown at reactive/src/main/java/feign/reactive/ReactiveDelegatingContract.java:58

      final Type type = metadata.returnType();
      if (!isReactive(type)) {
        throw new IllegalArgumentException(
            String.format(
                "Method %s of contract %s doesn't returns a org.reactivestreams.Publisher",
                metadata.configKey(), targetType.getSimpleName()));
      }

      /*
       * we will need to change the return type of the method to match the return type contained
       * within the Publisher
       */
      Type[] actualTypes = ((ParameterizedType) type).getActualTypeArguments();
      if (actualTypes.length > 1) {
        throw new IllegalStateException("Expected only one contained type.");
      } else {
        Class<?> actual = Types.getRawType(actualTypes[0]);
        if (Stream.class.isAssignableFrom(actual)) {
          throw new IllegalArgumentException(
              "Streams are not supported when using Reactive Wrappers");
        }
        metadata.returnType(type);
      }
    }

    return methodsMetadata;
  }

  /**
   * Ensure that the type provided implements a Reactive Streams Publisher.
   *
   * @param type to inspect.
   * @return true if the type implements the Reactive Streams Publisher specification.
   */
  private boolean isReactive(Type type) {
    if (!ParameterizedType.class.isAssignableFrom(type.getClass())) {
      return false;

View on GitHub (pinned to e2a1e27560)