OpenFeign/feign · error · DecodeException
${e.toString()}
Error message
${e.toString()} What it means
JAXBDecoder.decode catches JAXBException, ParserConfigurationException and SAXException while unmarshalling the response body via SAX and rethrows them as a Feign DecodeException whose message is e.toString(). It means XML parsing/unmarshalling of the HTTP response failed - typically malformed XML, a root element that does not match the target type, or a class not correctly mapped via JAXBContextFactory.
Solutions
- Inspect e.getCause() in the DecodeException to see the actual JAXB/SAX error and fix the XML or the type mapping.
- Verify the server returns well-formed XML matching the annotated return type (root element, namespaces).
- Ensure target DTOs carry @XmlRootElement/@XmlElement annotations and are registered with the JAXBContextFactory.
- Catch DecodeException in caller code and log status plus cause for diagnostics.
Example fix
// before
MyDto dto = api.get(); // throws DecodeException on bad XML
// after
try {
MyDto dto = api.get();
} catch (DecodeException e) {
logger.error("decode failed status=" + e.status(), e.getCause());
} Defensive patterns
Strategy: try-catch
Validate before calling
// before calling
String ct = response.headers().getOrDefault("content-type", "").toLowerCase();
if (!ct.contains("xml")) throw new IllegalStateException("endpoint did not return XML: " + ct); Try / catch
try {
result = api.call();
} catch (DecodeException e) {
Throwable c = e.getCause();
if (c instanceof SAXException || c instanceof JAXBException) {
// malformed XML or mapping mismatch; log and fall back
} else { throw e; }
} Prevention
- Validate endpoints return well-formed XML with an application/xml or text/xml content type.
- Keep DTO @XmlRootElement/@XmlElement annotations in sync with the server schema, including namespaces.
- Test decode paths with contract tests using sample payloads.
- Always inspect DecodeException.getCause(), not just its message.
When it happens
Trigger: decode() is invoked on a response whose body is not well-formed XML, or whose XML does not match the @XmlRootElement-annotated target type; also raised when SAX parser creation fails or the underlying input stream errors during unmarshal.
Common situations: Server returns an HTML error page instead of XML; response XML root element or namespaces don't match the declared return type; missing @XmlRootElement on the DTO causing JAXBException; response truncated by a proxy.
Related errors
- ${e.toString()}
- JAXB only supports decoding raw types. Found
- JAXB only supports decoding raw types. Found
- JAXBContextFactory must be non-null
- JAXB only supports encoding raw types. Found
AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10).
Data as JSON: /api/errors/9279b2f2016d950c.
Report an issue: GitHub.
Appendix: source
Thrown at jaxb-jakarta/src/main/java/feign/jaxb/JAXBDecoder.java:97
try {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
/* Explicitly control sax configuration to prevent XXE attacks */
saxParserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxParserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false);
saxParserFactory.setFeature(
"http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
saxParserFactory.setNamespaceAware(namespaceAware);
return jaxbContextFactory
.createUnmarshaller((Class<?>) type)
.unmarshal(
new SAXSource(
saxParserFactory.newSAXParser().getXMLReader(),
new InputSource(response.body().asInputStream())));
} catch (JAXBException | ParserConfigurationException | SAXException e) {
throw new DecodeException(response.status(), e.toString(), response.request(), e);
} finally {
if (response.body() != null) {
response.body().close();
}
}
}
public static class Builder {
private boolean namespaceAware = true;
private JAXBContextFactory jaxbContextFactory;
/** Controls whether the underlying XML parser is namespace aware. Default is true. */
public Builder withNamespaceAware(boolean namespaceAware) {
this.namespaceAware = namespaceAware;
return this;
}
public Builder withJAXBContextFactory(JAXBContextFactory jaxbContextFactory) {View on GitHub (pinned to e2a1e27560)