OpenFeign/feign · error · DecodeException
is not a type supported by this decoder.
Error message
{type} is not a type supported by this decoder. What it means
StringDecoder only knows how to decode HTTP response bodies into java.lang.String (returning null for 404/204/empty bodies). When handed any other target type it throws this DecodeException, meaning the configured decoder does not support the method's return type. The thrown message names the unsupported type.
Solutions
- Register a decoder matching the return type, e.g. JacksonDecoder/GsonDecoder for POJOs, keeping StringDecoder for String methods via MultiDecoder
- Change the interface method's return type to String if you only need the raw body
- Use Decoder.Default (or a MultiDecoder chain ending in a default) instead of StringDecoder alone
Example fix
// before
Feign.builder().decoder(new StringDecoder()).target(Api.class, url); // method returns User
// after
Feign.builder().decoder(new MultiDecoder.Builder()
.add(new JacksonDecoder())
.add(new StringDecoder())
.build()).target(Api.class, url); Defensive patterns
Strategy: type-guard
Validate before calling
// ensure decoder supports the method return type before the call
if (!String.class.equals(returnType)
&& decoder instanceof feign.codec.StringDecoder) {
throw new ConfigurationException(
"StringDecoder cannot decode " + returnType + "; register a matching decoder");
} Type guard
static boolean stringDecoderSupports(Type type) {
return type instanceof Class<?> c && String.class.equals(c);
} Try / catch
try {
return api.call();
} catch (DecodeException e) {
if (e.getMessage().endsWith("is not a type supported by this decoder.")) {
throw new ClientConfigurationException(
"Return type not supported by configured decoder: " + e.getMessage(), e);
}
throw e;
} Prevention
- Only use StringDecoder for methods returning java.lang.String
- Use MultiDecoder to pair StringDecoder with a JSON decoder for object types
- Prefer Decoder.Default over StringDecoder when you also need byte[] support
- Keep interface return types and registered decoders in sync; review on return-type changes
When it happens
Trigger: Configuring Feign with StringDecoder (directly or via ErrorDecoder/test paths that use it) while an interface method returns a non-String type such as a POJO, Response, Map, or generic type; the call decodes a 2xx non-empty body and then fails the String.class.equals(type) check.
Common situations: Using StringDecoder as the only decoder and expecting automatic JSON binding; test harnesses delegating to StringDecoder with non-String expected types; switching a method's return type from String to an object without changing decoders; confusing StringDecoder with Decoder.Default (which handles String and byte[]).
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unable to decode response ( ) ...
- is not a type supported by this decoder.
- Status Code [ ] has already been declared to throw [ ] and…
- Cannot generate exception - check constructor parameter…
- Too many constructors marked with @FeignExceptionConstructor
AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10).
Data as JSON: /api/errors/3558ccf74b0d4162.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/feign/codec/StringDecoder.java:52
*/
@Override
public boolean canDecode(Response response, Type type) {
return response.status() == 404
|| response.status() == 204
|| response.body() == null
|| String.class.equals(type);
}
@Override
public Object decode(Response response, Type type) throws IOException {
Response.Body body = response.body();
if (response.status() == 404 || response.status() == 204 || body == null) {
return null;
}
if (String.class.equals(type)) {
return Util.toString(body.asReader(response.charset()));
}
throw new DecodeException(
response.status(),
format("%s is not a type supported by this decoder.", type),
response.request());
}
}
View on GitHub (pinned to e2a1e27560)