📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 6.8-8.9

1. 问题含义 #

could not parse http request. unexpected object field [field] 表示请求对象里某个字段被写成了 JSON 对象,但当前解析器只接受少数字段为对象。根据源码片段,headersparams 可以是对象,其余字段一旦给对象就会报错。

常见误用是把 body 直接写成对象,或者把 urlpathhost 包成嵌套结构。

2. 直接原因 #

  • body 被直接写成对象而不是字符串。
  • 本应平铺的字段被套进一层 JSON 对象。
  • 把别的 HTTP 客户端配置原样复制进 Watcher 请求对象。

3. 排查步骤 #

  1. 根据异常字段名判断该对象是否本就应该是 headersparams
  2. 如果是 body,确认是否应该先转成字符串。
  3. 检查 headersparams 下的值是否继续满足解析器要求。
  4. 用最小请求体验证,只保留 hostpathmethod 等基本字段后再回填。

4. 修复示例 #

错误示例:

{
  "request": {
    "host": "api.example.com",
    "body": {
      "query": {
        "match_all": {}
      }
    }
  }
}

正确示例:

{
  "request": {
    "host": "api.example.com",
    "headers": {
      "Content-Type": "application/json"
    },
    "params": {
      "pretty": "true"
    },
    "body": "{\"query\":{\"match_all\":{}}}"
  }
}

5. 相关错误 #

附:日志上下文 #

    } else if (Field.PARAMS.match(currentFieldName, parser.getDeprecationHandler())) {
        builder.setParams(headers);
    } else if (Field.BODY.match(currentFieldName, parser.getDeprecationHandler())) {
        builder.body(parser.text());
    } else {
        throw new ElasticsearchParseException("could not parse http request. unexpected object field [{}]",
            currentFieldName);
    }
} else if (token == XContentParser.Token.VALUE_STRING) {
    if (Field.SCHEME.match(currentFieldName, parser.getDeprecationHandler())) {
        builder.scheme(Scheme.parse(parser.text()));