OpenFeign/feign · error · EncodeException
Failure encoding object into query map
Error message
Failure encoding object into query map
What it means
BeanQueryMapEncoder converts a bean-style object into a query-parameter map by reading its properties via the JavaBeans Introspector. If reflection on the bean fails — a getter is not accessible, introspection of the class fails, or the underlying getter throws — Feign wraps the cause in EncodeException with this message.
Solutions
- Fix or remove the getter on the query-map bean that throws the wrapped InvocationTargetException
- Ensure query-map objects are proper JavaBeans: public class with public no-arg constructor and public getters
- Catch EncodeException around the Feign call and inspect getCause() to identify which property failed
- Make the bean class/methods accessible (public) if IllegalAccessException is the cause
Example fix
// before
Feign.builder().queryMapEncoder(new BeanQueryMapEncoder())
.target(Api.class, "https://api");
// used with a class whose getter throws:
public class Params { public String getQ() { throw new IllegalStateException("uninitialized"); } }
// after
public class Params {
private String q = "";
public String getQ() { return q; } // getter must not throw
public void setQ(String q) { this.q = q; }
} Defensive patterns
Strategy: try-catch
Validate before calling
for (PropertyDescriptor pd : Introspector.getBeanInfo(params.getClass()).getPropertyDescriptors()) {
if (pd.getReadMethod() == null || !Modifier.isPublic(pd.getReadMethod().getDeclaringClass().getModifiers()))
throw new IllegalStateException("query-map bean property not readable: " + pd.getName());
} Type guard
boolean isValidQueryMapBean(Object o) {
return o != null && Modifier.isPublic(o.getClass().getModifiers());
} Try / catch
try {
api.search(params);
} catch (EncodeException e) {
throw new IllegalArgumentException("bad query map bean: " + e.getCause(), e);
} Prevention
- Use proper JavaBeans: public class, public getters, no-arg constructor
- Keep getters side-effect free; never throw from them
- Keep query-map values initialized before calling the client
- Log getCause() when wrapping EncodeException to find the failing property
When it happens
Trigger: Calling Feign with a @QueryMap-bound bean whose getters throw, whose property descriptors cannot be introspected (IntrospectionException), or whose getter method is inaccessible to the encoder (IllegalAccessException / InvocationTargetException).
Common situations: Passing non-bean or oddly-shaped objects (no public getters) as @QueryMap; beans with getter methods that throw NPEs on internal state; running under a SecurityManager/strict module access that blocks reflective getter calls; class changes after introspection metadata was cached.
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
- Failure encoding object into query map
- Cannot generate exception - check constructor parameter…
- Too many constructors marked with @FeignExceptionConstructor
- Cannot find any suitable constructor in class
- Cannot access constructor
AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10).
Data as JSON: /api/errors/2138417451662ede.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/feign/querymap/BeanQueryMapEncoder.java:60
public Map<String, Object> encode(Object object) throws EncodeException {
if (object == null) {
return Collections.emptyMap();
}
try {
ObjectParamMetadata metadata = getMetadata(object.getClass());
Map<String, Object> propertyNameToValue = new HashMap<String, Object>();
for (PropertyDescriptor pd : metadata.objectProperties) {
Method method = pd.getReadMethod();
Object value = method.invoke(object);
if (value != null && value != object) {
Param alias = method.getAnnotation(Param.class);
String name = alias != null ? alias.value() : pd.getName();
propertyNameToValue.put(name, value);
}
}
return propertyNameToValue;
} catch (IllegalAccessException | IntrospectionException | InvocationTargetException e) {
throw new EncodeException("Failure encoding object into query map", e);
}
}
private ObjectParamMetadata getMetadata(Class<?> objectType) throws IntrospectionException {
ObjectParamMetadata metadata = classToMetadata.get(objectType);
if (metadata == null) {
metadata = ObjectParamMetadata.parseObjectType(objectType);
classToMetadata.put(objectType, metadata);
}
return metadata;
}
private static class ObjectParamMetadata {
private final List<PropertyDescriptor> objectProperties;
private ObjectParamMetadata(List<PropertyDescriptor> objectProperties) {
this.objectProperties = Collections.unmodifiableList(objectProperties);View on GitHub (pinned to e2a1e27560)