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
- Declare the method return type as a concrete class (List<MyType> is fine since the raw type is used).
- Create one non-generic interface per concrete SOAP response type.
- 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
- Use concrete classes for SOAP method return types.
- Avoid type-variable returns in javax-soap Feign interfaces.
- Add a reflection-based test asserting decodable types.
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
- SOAP only supports decoding raw types. Found
- SOAP only supports encoding raw types. Found
- SOAP only supports encoding raw types. Found
- JAXB only supports decoding raw types. Found
- Not supported type
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)