适用版本: 6.8-8.11
1. 错误异常的基本描述 #
failed to find low and high distance values 表示 Elasticsearch 在解析模糊查询(fuzziness)的 AUTO 模式自定义阈值时,无法从传入的字符串中提取出合法的 low 和 high 两个整数值。该异常属于 parse_exception,通常在查询 DSL 解析阶段抛出,请求尚未真正执行就会被拒绝。
常见现象 #
- 查询请求返回
400 Bad Request,响应体中包含failed to find low and high distance values错误信息。 - 使用
AUTO格式设置模糊度时,无论查询本身是否合理,只要fuzziness参数格式不正确就会直接报错。 - 在应用日志或 Elasticsearch 服务端日志中可以看到
ElasticsearchParseException或NumberFormatException相关的异常栈。 - 如果是通过模板、前端表单或动态拼接生成
fuzziness值,问题往往集中出现在特定输入条件下,表现为间歇性失败。
典型报错与异常栈 #
ElasticsearchParseException: failed to parse [AUTO:3] as "auto:int,int"
Caused by: java.lang.NumberFormatException: For input string: ""
at org.elasticsearch.common.lucene.search.fuzziness.Fuzziness.parse(AUTO:3)
2. 为什么会发生这个错误 #
fuzziness 参数支持以下格式:
| 格式 | 说明 |
|---|---|
0、1、2 | 固定编辑距离 |
AUTO | 默认阈值(low=3, high=6) |
AUTO:low,high | 自定义阈值,如 AUTO:2,5 |
AUTO:low,high,max_expansions | 自定义阈值及最大扩展数(部分版本支持) |
当使用 AUTO:low,high 格式时,Elasticsearch 会按冒号和逗号分割字符串,并期望得到两个整数。如果分割后无法得到恰好两个整数,就会抛出 failed to find low and high distance values。
常见原因包括:
- 格式不完整:只写了
AUTO:3,缺少high值,冒号后只有一个数字。 - 分隔符错误:使用了分号
;、空格、中文逗号,或全角字符,而不是英文逗号,。 - 阈值非整数:
low或high位置为空字符串、包含字母或其他非法字符,无法解析为int。 - 拼接逻辑缺陷:业务代码动态拼接
fuzziness值时,变量为空或类型错误,生成了AUTO:、AUTO:null,6等非法字符串。 - 模板渲染残留:模板语言中变量未正常替换,最终传入了
AUTO:{{low}},{{high}}这类原始占位符文本。
3. 如何排查和解决这个异常 #
建议按以下步骤定位问题:
- 抓取完整请求 DSL:从应用日志或 Elasticsearch 慢查询日志中获取最终发送到 Elasticsearch 的查询体,重点检查
fuzziness字段的实际值。 - 确认 fuzziness 格式:如果使用
AUTO自定义阈值,确保格式严格为AUTO:low,high,即冒号后紧跟两个整数,中间用英文逗号分隔。 - 检查拼接来源:如果
fuzziness值来自前端输入、配置文件或模板渲染,回溯生成逻辑,确认变量是否可能为空或类型错误。 - 简化复现:先用标准
AUTO或固定整数(如2)替换当前值,验证查询本身是否合法,排除其他参数干扰。 - 查看日志上下文:结合 Elasticsearch 服务端日志中的异常栈,确认是在解析哪个字段、哪段字符串时失败。
排查时需要注意的问题 #
- 不要只看
fuzziness的默认值,要检查所有动态赋值路径,包括默认值和覆盖逻辑。 - 如果项目中使用了多个搜索入口(如搜索接口、建议接口、补全接口),需要逐一确认各入口的
fuzziness构造方式是否一致。 - 注意
AUTO格式在 Elasticsearch 不同版本中的细微差异,低版本不支持AUTO:low,high,max_expansions形式。
4. 如何解决这个错误 #
常用修复思路 #
- 修正格式:将不完整的
AUTO:3改为完整格式AUTO:3,6,或直接改用标准AUTO。 - 统一分隔符:确保使用英文冒号
:和英文逗号,,避免使用全角符号或空格。 - 增加参数校验:在业务代码中为
fuzziness参数增加格式校验,非法值直接拒绝或给出明确报错,避免把脏数据传给 Elasticsearch。 - 兜底默认值:当
low或high变量为空时,使用合理的默认值(如AUTO:3,6)而非拼接出半截字符串。 - 模板占位符清理:如果使用模板引擎,确保占位符在渲染后有合法的 fallback 值。
修复示例 #
{
"query": {
"match": {
"title": {
"query": "elasticsearch",
"fuzziness": "AUTO:2,5"
}
}
}
}
// Java 示例:安全地构造 fuzziness 值
int low = getLowThreshold(); // 可能为 null 或 0
int high = getHighThreshold();
String fuzziness;
if (low > 0 && high > 0) {
fuzziness = "AUTO:" + low + "," + high;
} else {
fuzziness = "AUTO"; // 兜底为默认阈值
}
借助 INFINI 产品提升排障效率 #
- INFINI Console 可以查看查询请求详情、DSL 内容和错误趋势,帮助快速定位是哪一类查询在产生格式错误。
- INFINI Gateway 可以部署在 Elasticsearch 前面,对请求做校验、改写和审计,在非法
fuzziness值到达后端之前进行拦截和修正。
5. 小结 #
failed to find low and high distance values 本质上是 fuzziness 参数格式错误,核心原因是 AUTO:low,high 字符串没有严格按照 冒号 + 两个整数 + 逗号 的格式提供。排查时优先确认最终发送到 Elasticsearch 的 DSL 中 fuzziness 的实际值,修复时重点做好参数校验和兜底处理,避免把不完整的字符串直接传给搜索引擎。
相关错误 #
附:日志上下文 #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
try {
// 解析 AUTO:low,high 格式
String[] parts = fuzzinessString.split("[:]")[1].split("[,]");
int low = Integer.parseInt(parts[0]);
int high = Integer.parseInt(parts[1]);
return Fuzziness.buildAUTO(low, high);
} catch (NumberFormatException e) {
throw new ElasticsearchParseException(
"failed to parse [{}] as \"auto:int,int\"", e, fuzzinessString);
}





