OpenFeign/feign · error · UnsupportedOperationException

JAXB only supports encoding raw types. Found

Error message

JAXB only supports encoding raw types. Found ${bodyType}

What it means

Same as error 102 in the javax jaxb module: JAXBEncoder rejects non-Class (generic/ParameterizedType) body types with UnsupportedOperationException because JAXB marshalling requires a raw annotated root class.

Solutions

  1. Change the request body type to a single @XmlRootElement-annotated class.
  2. Introduce a wrapper DTO holding the collection.
  3. Use a JSON encoder for generic body types.

Example fix

// before
void post(List<Order> orders);
// after
@XmlRootElement class Orders { @XmlElement(name="order") List<Order> list; }
void post(Orders orders);
Defensive patterns

Strategy: type-guard

Validate before calling

// before calling the endpoint
if (!(bodyType instanceof Class)) {
  throw new IllegalArgumentException("use a raw @XmlRootElement class for JAXB request bodies");
}

Type guard

boolean rawClass(java.lang.reflect.Type t) {
  return t instanceof Class;
}

Try / catch

try {
  api.post(obj);
} catch (UnsupportedOperationException e) {
  // restructure the body type into an @XmlRootElement wrapper
}

Prevention

When it happens

Trigger: encode() called with bodyType such as List<Foo> or Map<String,Foo> when using JAXBEncoder.

Common situations: POSTing collections or generic wrappers with JAXB; expecting collection marshalling analogous to JSON encoders.

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/c2642747d5ba266c. Report an issue: GitHub.

Appendix: source

Thrown at jaxb/src/main/java/feign/jaxb/JAXBEncoder.java:58

 *     .encoder(new JAXBEncoder(jaxbFactory))
 *     .target(MyApi.class, "http://api");
 * </pre>
 *
 * <p>The JAXBContextFactory should be reused across requests as it caches the created JAXB
 * contexts.
 */
public class JAXBEncoder implements Encoder, PredicatedEncoder {

  private final JAXBContextFactory jaxbContextFactory;

  public JAXBEncoder(JAXBContextFactory jaxbContextFactory) {
    this.jaxbContextFactory = jaxbContextFactory;
  }

  @Override
  public void encode(Object object, Type bodyType, RequestTemplate template) {
    if (!(bodyType instanceof Class)) {
      throw new UnsupportedOperationException(
          "JAXB only supports encoding raw types. Found " + bodyType);
    }
    try {
      Marshaller marshaller = jaxbContextFactory.createMarshaller((Class<?>) bodyType);
      StringWriter stringWriter = new StringWriter();
      marshaller.marshal(object, stringWriter);
      template.body(stringWriter.toString());
    } catch (JAXBException e) {
      throw new EncodeException(e.toString(), e);
    }
  }

  @Override
  public boolean canEncode(Object object, Type bodyType, RequestTemplate template) {
    return Util.isXmlContentType(template);
  }
}

View on GitHub (pinned to e2a1e27560)