{"record":{"id":"ccc58da9249bafc0","repo":"OpenFeign/feign","slug":"unable-to-encode-bodytype-headers","errorCode":null,"errorMessage":"Unable to encode {bodyType} ({headers}) ...","messagePattern":"Unable to encode (.+?) \\((.+?)\\) \\.\\.\\.","errorType":"exception","errorClass":"EncodeException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/feign/codec/MultiEncoder.java","lineNumber":109,"sourceCode":"\n  /**\n   * Encodes using the first encoder that accepts the request.\n   *\n   * @param object {@inheritDoc}\n   * @param bodyType {@inheritDoc}\n   * @param template {@inheritDoc}\n   * @throws EncodeException when no encoder accepts the request, or the chosen one fails\n   */\n  @Override\n  public void encode(Object object, Type bodyType, RequestTemplate template)\n      throws EncodeException {\n    for (PredicatedEncoder encoder : encoders) {\n      if (encoder.canEncode(object, bodyType, template)) {\n        encoder.encode(object, bodyType, template);\n        return;\n      }\n    }\n    throw new EncodeException(unableToEncode(bodyType, template));\n  }\n\n  private String unableToEncode(Type bodyType, RequestTemplate template) {\n    StringBuilder message =\n        new StringBuilder(\"Unable to encode \")\n            .append(bodyType == null ? \"request body\" : bodyType.getTypeName())\n            .append(\" (\")\n            .append(headers(template))\n            .append(')');\n    if (template.method() != null) {\n      message.append(\" for \").append(template.method()).append(' ').append(template.path());\n    }\n    message.append(\". Encoders tried, in order:\");\n    appendTo(message, \"\\n  \");\n    return message\n        .append(\"\\nRegister an encoder that accepts it, or add a catch-all\")\n        .append(\" (EncoderPredicate.any()) last.\")\n        .toString();","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/core/src/main/java/feign/codec/MultiEncoder.java#L91-L127","documentation":"Feign's MultiEncoder iterates its registered PredicatedEncoders and throws this EncodeException when none of them declares it can encode the request body for the given bodyType. The message includes the body type and template headers, indicating the encoder chain lacks coverage for this request shape. It is thrown before any HTTP call is made.","triggerScenarios":"Sending a request with a body (e.g. a @Body or @Param object) whose Java type (e.g. a POJO without a JSON encoder registered, or a Map with form encoding expected) matches no registered encoder's canEncode predicate in the MultiEncoder chain.","commonSituations":"Building a client with only a decoder but no encoder, then POSTing an object; forgetting to register JacksonEncoder/GsonEncoder; sending a raw String/byte[] when the registered encoder only handles JSON types; switching an endpoint from form params to a JSON body without updating encoders.","solutions":["Register a matching encoder, e.g. Feign.builder().encoder(new JacksonEncoder()) or add it to the MultiEncoder.Builder chain","Add a fallback encoder (e.g. new Encoder.Default() which handles String/byte[]) as the last entry","Check the body type in the message and confirm it is the type your interface method actually sends; align the method signature or encoder predicate","Verify the relevant codec module (feign-jackson, feign-gson, etc.) is on the classpath"],"exampleFix":"// before\nFeign.builder().decoder(new JacksonDecoder()).target(Api.class, url); // POST fails\n// after\nFeign.builder()\n    .encoder(new MultiEncoder.Builder().add(new JacksonEncoder()).add(new Encoder.Default()).build())\n    .decoder(new JacksonDecoder())\n    .target(Api.class, url);","handlingStrategy":"validation","validationCode":"// verify every @Body/@Param object type in the target interface has an encoder\nfor (Method m : apiInterface.getMethods()) {\n  Class<?> bodyType = bodyParamType(m);\n  if (bodyType != null && !encoders.stream().anyMatch(e -> e.canEncode(bodyType.newInstance(), bodyType, new RequestTemplate()))) {\n    throw new ConfigurationException(\"No encoder registered for \" + bodyType);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  return api.post(payload);\n} catch (EncodeException e) {\n  if (e.getMessage().startsWith(\"Unable to encode\")) {\n    throw new ClientConfigurationException(\"No encoder for body type: \" + e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["Always register an encoder when the interface sends request bodies (JacksonEncoder/GsonEncoder/Encoder.Default)","End MultiEncoder chains with Encoder.Default as a fallback for String/byte[] bodies","Confirm the codec module dependency is present before wiring its encoder","Review encoder coverage when changing an endpoint from form params to a body"],"tags":["feign","encoding","request-body","configuration"],"backgroundTag":"incompatible-source-type","analyzedSha":"e2a1e27560a1e68840c34f031afca88b36096e30","analyzedAt":"2026-09-10T12:37:37.238Z","contentChangedAt":"2026-09-10T12:37:37.238Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}