OpenFeign/feign · error · DecodeException
is not a type supported by this decoder.
Error message
%s is not a type supported by this decoder.
What it means
JsonDecoder.decode (feign-json, built on org.json) supports only Map, JSONObject, JSONArray and String return types. When a 404/204 response is decoded to any other type, it throws DecodeException saying the type is not supported; the decoder parses JSON into org.json structures and cannot bind arbitrary POJOs.
Solutions
- Change the method return type to Map, JSONObject, JSONArray, or String.
- For 404/204 endpoints, return a supported type (Map or String yields null; JSONObject/JSONArray yield empty objects).
- Switch to the Jackson or Gson module for POJO decoding.
- Catch DecodeException around calls to not-found-prone endpoints.
Example fix
// before UserDto getUser(); // 404 -> DecodeException // after org.json.JSONObject getUser(); // returns new JSONObject() on 404/204
Defensive patterns
Strategy: type-guard
Validate before calling
// before declaring a feign-json method typeCheck(returnType);
Type guard
boolean isJsonDecoderType(java.lang.reflect.Type t) {
if (!(t instanceof Class)) return false;
Class<?> c = (Class<?>) t;
return Map.class.equals(c) || JSONObject.class.isAssignableFrom(c)
|| JSONArray.class.isAssignableFrom(c) || String.class.equals(c);
} Try / catch
try {
result = api.get();
} catch (DecodeException e) {
if (e.status() == 404 || e.status() == 204) {
// unsupported return type on empty/not-found response; adjust type or handle
} else { throw e; }
} Prevention
- Restrict feign-json methods to Map/JSONObject/JSONArray/String returns.
- Use the Jackson or Gson module for POJO mapping.
- Handle 404/204 endpoints with supported return types.
When it happens
Trigger: Declaring a Feign method returning a custom POJO (e.g. MyDto) with JsonDecoder, and the server responds 404 or 204; the empty-body branch cannot map the declared type and throws.
Common situations: Using feign-json expecting POJO binding like Jackson/Gson; typed DTO returns on no-content or not-found endpoints; migrating from another decoder module.
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
- is not a type supported by this encoder.
- JAXB only supports decoding raw types. Found
- ${jsonException.getMessage()}
- is not a type supported by this encoder.
- ${e.getMessage()}
AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10).
Data as JSON: /api/errors/f76060a6dfe64c7c.
Report an issue: GitHub.
Appendix: source
Thrown at json/src/main/java/feign/json/JsonDecoder.java:67
* .decoder(new JsonDecoder())
* .target(GitHub.class, "https://api.github.com");
*
* JSONArray contributors = github.contributors("openfeign", "feign");
*
* System.out.println(contributors.getJSONObject(0).getString("login"));
* </pre>
*/
public class JsonDecoder implements Decoder, PredicatedDecoder, feign.codec.JsonDecoder {
@Override
public Object decode(Response response, Type type) throws IOException, DecodeException {
if (response.status() == 404 || response.status() == 204)
if (Map.class.equals(type)) return null;
else if (JSONObject.class.isAssignableFrom((Class<?>) type)) return new JSONObject();
else if (JSONArray.class.isAssignableFrom((Class<?>) type)) return new JSONArray();
else if (String.class.equals(type)) return null;
else
throw new DecodeException(
response.status(),
format("%s is not a type supported by this decoder.", type),
response.request());
if (response.body() == null) return null;
try (Reader reader = response.body().asReader(response.charset())) {
Reader bodyReader = (reader.markSupported()) ? reader : new BufferedReader(reader);
bodyReader.mark(1);
if (bodyReader.read() == -1) {
return null; // Empty body
}
bodyReader.reset();
return decodeBody(response, type, bodyReader);
} catch (JSONException jsonException) {
if (jsonException.getCause() != null && jsonException.getCause() instanceof IOException) {
throw (IOException) jsonException.getCause();
}
throw new DecodeException(
response.status(), jsonException.getMessage(), response.request(), jsonException);View on GitHub (pinned to e2a1e27560)