OpenFeign/feign · error · EncodeException
${e.getMessage()}
Error message
${e.getMessage()} What it means
This wraps any unexpected RuntimeException thrown while encoding form variables into an EncodeException, preserving the original message and cause. Feign does this so callers can catch a single codec exception type when template resolution fails. It is a pass-through wrapper, not a distinct failure mode.
Solutions
- Read the wrapped cause (e.getCause()) to find the real encoder failure
- Fix the underlying encoder bug or configuration revealed by the cause
- Register a proper Encoder (e.g. Jackson/Gson) that handles the form map types
- Add unit tests around the Encoder with the actual payload
Example fix
// before Feign.builder().encoder(new JacksonEncoder()) // no ObjectMapper configured -> NPE wrapped as EncodeException // after Feign.builder().encoder(new JacksonEncoder(new ObjectMapper()))
Defensive patterns
Strategy: try-catch
Validate before calling
// verify encoder handles the form map
if (!(encoder instanceof feign.codec.Encoder)) throw new IllegalStateException("encoder required"); Type guard
if (encoder == null) { /* configure before building client */ } Try / catch
try { api.submit(form); } catch (EncodeException e) { log.error("encode failed: {}", e.getMessage(), e.getCause()); throw new ClientConfigException(e); } Prevention
- Always configure a concrete encoder on Feign.builder()
- Log the cause chain, not just the message
- Unit-test encoders with real payloads
- Keep encoder configuration (ObjectMapper etc.) centralized
When it happens
Trigger: A @Form/@Body form-encoding request is resolved via RequestTemplateFactoryResolver$FormFieldResolver.resolve and the configured Encoder throws a RuntimeException (e.g. NPE inside Jackson/Gson encoder) while encoding the form variables map.
Common situations: A custom Encoder throws unchecked exceptions; a JSON encoder is misconfigured (no ObjectMapper set) or receives an unencodable object; null field values in form data trip encoder internals.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- is not a type supported by this encoder.
- Failure encoding object into query map
- Failure encoding object into query map
- Status Code [ ] has already been declared to throw [ ] and…
- Cannot generate exception - check constructor parameter…
AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10).
Data as JSON: /api/errors/b3d48575983af2dc.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/feign/RequestTemplateFactoryResolver.java:239
super(metadata, queryMapEncoder, target);
this.encoder = encoder;
}
@Override
protected RequestTemplate resolve(
Object[] argv, RequestTemplate mutable, Map<String, Object> variables) {
Map<String, Object> formVariables = new LinkedHashMap<String, Object>();
for (Map.Entry<String, Object> entry : variables.entrySet()) {
if (metadata.formParams().contains(entry.getKey())) {
formVariables.put(entry.getKey(), entry.getValue());
}
}
try {
encoder.encode(formVariables, Encoder.MAP_STRING_WILDCARD, mutable);
} catch (EncodeException e) {
throw e;
} catch (RuntimeException e) {
throw new EncodeException(e.getMessage(), e);
}
return super.resolve(argv, mutable, variables);
}
}
static class BuildEncodedTemplateFromArgs extends BuildTemplateByResolvingArgs {
private final Encoder encoder;
BuildEncodedTemplateFromArgs(
MethodMetadata metadata, Encoder encoder, QueryMapEncoder queryMapEncoder, Target target) {
super(metadata, queryMapEncoder, target);
this.encoder = encoder;
}
@Override
protected RequestTemplate resolve(
Object[] argv, RequestTemplate mutable, Map<String, Object> variables) {View on GitHub (pinned to e2a1e27560)