OpenFeign/feign · error · UnsupportedOperationException

SOAP only supports decoding raw types. Found

Error message

SOAP only supports decoding raw types. Found %s

What it means

Same check as its jakarta sibling in the javax-based soap module: SOAPDecoder.decode() unwraps ParameterizedTypes to raw types and requires the result to be a Class, since JAXB unmarshalling needs a Class. Otherwise it throws UnsupportedOperationException naming the offending type.

Solutions

  1. Declare the method return type as a concrete class (List<MyType> is fine since the raw type is used).
  2. Create one non-generic interface per concrete SOAP response type.
  3. Wrap SOAPDecoder with a custom Decoder that substitutes type variables with concrete classes first.

Example fix

// before
public interface Api<T> { T find(); }
// after
public interface OrderApi { Order find(); }
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isSoapDecodable(Type type) {
  while (type instanceof ParameterizedType) {
    type = ((ParameterizedType) type).getRawType();
  }
  return type instanceof Class;
}

Type guard

if (!isSoapDecodable(returnType)) {
  throw new IllegalArgumentException("SOAP return type must resolve to a raw Class");
}

Try / catch

try {
  return client.find();
} catch (UnsupportedOperationException e) {
  if (e.getMessage() != null && e.getMessage().contains("SOAP only supports decoding raw types")) {
    // replace generic return type with a concrete class
  }
  throw e;
}

Prevention

When it happens

Trigger: A Feign method in a javax-soap client returns a type that is not resolvable to a raw Class (type variable, wildcard, or other non-Class Type) and the method is invoked, triggering decode() on the SOAP response.

Common situations: Generic interface methods with type-variable return types; frameworks passing unresolved generic signatures; migrating code that used raw Object returns.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at soap/src/main/java/feign/soap/SOAPDecoder.java:110

    this.useFirstChild = false;
  }

  private SOAPDecoder(Builder builder) {
    this.soapProtocol = builder.soapProtocol;
    this.jaxbContextFactory = builder.jaxbContextFactory;
    this.useFirstChild = builder.useFirstChild;
  }

  @Override
  public Object decode(Response response, Type type) throws IOException {
    if (response.status() == 404) return Util.emptyValueOf(type);
    if (response.body() == null) return null;
    while (type instanceof ParameterizedType) {
      ParameterizedType ptype = (ParameterizedType) type;
      type = ptype.getRawType();
    }
    if (!(type instanceof Class)) {
      throw new UnsupportedOperationException(
          "SOAP only supports decoding raw types. Found " + type);
    }

    try {
      SOAPMessage message =
          MessageFactory.newInstance(soapProtocol)
              .createMessage(null, response.body().asInputStream());
      if (message.getSOAPBody() != null) {
        if (message.getSOAPBody().hasFault()) {
          throw new SOAPFaultException(message.getSOAPBody().getFault());
        }

        Unmarshaller unmarshaller = jaxbContextFactory.createUnmarshaller((Class<?>) type);

        if (this.useFirstChild) {
          return unmarshaller.unmarshal(message.getSOAPBody().getFirstChild());
        } else {
          return unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());

View on GitHub (pinned to e2a1e27560)