适用版本: 6.8-8.11
1. 错误异常的基本描述 #
invalid time minute value. expected string/number value or an array of string/number values; but found [token] 是 Elasticsearch Watcher 功能在解析定时触发器(schedule trigger)中的 minute 字段时抛出的异常。
该错误表明 minute 配置的顶层结构不符合 Watcher 调度器的预期格式。Watcher 的 cron 风格时间配置只允许两种合法形态:
- 单个值:整数或字符串形式的分钟数,如
15或"15" - 数组:由整数或字符串分钟数组成的数组,如
[15, 30, 45]
一旦解析器在顶层遇到对象({})、布尔值(true/false)、null 或其他非预期类型,就会在展开数组之前直接抛出异常,导致整个 Watcher 无法注册或更新。
常见现象 #
- 调用
_watcherAPI 创建或更新 Watch 时,Elasticsearch 返回400 Bad Request,响应体中包含上述异常信息。 - Kibana 的 Watcher 管理界面可能提示"Failed to create watch"或"Invalid schedule configuration"。
- 已有的 Watch 在集群升级或配置热更新时可能因格式问题而加载失败,导致定时任务不再触发。
- 开发或运维人员在 Dev Tools 中执行 PUT 请求时,立即收到解析错误,无法直接保存配置。
典型报错与异常栈 #
报错通常出现在以下场景的响应中:
{
"error": {
"root_cause": [
{
"type": "elasticsearch_parse_exception",
"reason": "invalid time minute value. expected string/number value or an array of string/number values; but found [START_OBJECT]"
}
],
"type": "elasticsearch_parse_exception",
"reason": "invalid time minute value. expected string/number value or an array of string/number values; but found [START_OBJECT]"
},
"status": 400
}
服务端日志中可能出现类似下面的异常栈:
org.elasticsearch.common.ParsingException: invalid time minute value. expected string/number value or an array of string/number values; but found [START_OBJECT]
at org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTrigger.parseSchedule(ScheduleTrigger.java:...)
at org.elasticsearch.xpack.watcher.watch.WatchParser.parseTrigger(WatchParser.java:...)
...
ElasticsearchParseException、illegal_argument_exception、parse_exception 等关键字可能会与该错误同时出现,具体返回内容会因接口、版本与上下文而变化。
2. 为什么会发生这个错误 #
Watcher 的 schedule 配置中,minute 字段用于指定每小时内的哪些分钟触发执行。Elasticsearch 在解析该字段时,期望的 JSON 结构非常严格。
源码层面的约束 #
从 Elasticsearch 源码来看,minute 的解析逻辑大致如下:
- 读取当前 JSON token。
- 如果是数值(
VALUE_NUMBER)或字符串(VALUE_STRING),按单个分钟值处理。 - 如果是数组起始(
START_ARRAY),则遍历数组内的每个元素,要求每个元素都是数值或字符串。 - 如果以上都不匹配(例如遇到了
START_OBJECT、VALUE_BOOLEAN、VALUE_NULL等),则直接抛出ElasticsearchParseException,并提示invalid time minute value...。
常见错误原因 #
- 误将 minute 写成对象:例如
{"minute": {"from": 0, "to": 59}}或{"minute": {"values": [0, 15, 30, 45]}},这是把 minute 本身定义成了对象,而非预期的单值或数组。 - 误用 cron 表达式字符串:例如
"minute": "*/15",cron 表达式应写在cron字段中,而非minute字段。 - 模板渲染错误:使用外部模板引擎(如 Jinja2、Mustache)生成 Watch JSON 时,变量替换后产生了非预期的结构,例如
{{ minute_config }}渲染成了一个对象而非数组。 - 布尔值或 null 误入:例如
"minute": true或"minute": null,通常来自动态配置中条件分支的遗漏处理。 - 多层嵌套数组:例如
"minute": [[15, 30]],嵌套数组不符合解析器的预期,会直接报错。 - 从旧版本迁移时配置格式不兼容:某些早期版本的 Watcher 配置写法在新版本中不再被支持。
3. 如何排查和解决这个异常 #
建议按"先定位错误位置,再确认配置结构,最后修复并验证"的顺序处理:
排查步骤 #
- 获取完整报错信息:从 Elasticsearch 响应或日志中找到完整的异常信息,确认
but found [...]中的 token 类型,这能直接提示是哪种结构错了。 - 定位 Watch 配置:找到触发报错的 Watch ID,通过
GET _watcher/watch/<watch_id>获取完整配置,重点检查trigger.schedule下的minute字段。 - 检查 JSON 结构:确认
minute字段的顶层是数值、字符串还是数组,是否存在多余的对象包装。 - 回溯配置来源:如果 Watch 是通过脚本或模板生成的,检查生成逻辑是否正确输出了数组或单值,而非对象。
- 验证修复结果:修复后使用
PUT _watcher/watch/<watch_id>重新提交,确认不再报错,并通过GET _watcher/watch/<watch_id>/_status确认 Watch 已正常加载。
排查时需要注意的问题 #
- 不要只看报错表面的
minute,有时hour、day、month等字段也会出现类似的解析错误,需要一并检查整个schedule配置块。 - 如果 Watch 是通过 Kibana 界面创建的,注意界面上的"高级配置"模式可能允许输入任意 JSON,容易出现格式错误。
- 使用动态模板生成 Watch 时,务必在模板渲染后打印最终 JSON,确认结构符合预期,再提交到 Elasticsearch。
4. 如何解决这个错误 #
常用修复思路 #
修复方式一:将对象改为单值或数组 #
错误写法(对象形式):
{
"trigger": {
"schedule": {
"minute": { "values": [15, 30, 45] }
}
}
}
正确写法(数组形式):
{
"trigger": {
"schedule": {
"minute": [15, 30, 45]
}
}
}
正确写法(单值形式):
{
"trigger": {
"schedule": {
"minute": 30
}
}
}
修复方式二:将 cron 表达式移到正确字段 #
错误写法(在 minute 中使用 cron 表达式):
{
"trigger": {
"schedule": {
"minute": "*/15"
}
}
}
正确写法(使用 cron 字段):
{
"trigger": {
"schedule": {
"cron": "*/15 * * * *"
}
}
}
修复方式三:修复模板渲染逻辑 #
如果 Watch 是通过模板生成的,确保模板输出符合预期。例如使用 Jinja2 时:
错误的模板(可能输出对象):
"minute": {{ minute_config }}
如果 minute_config 是一个对象 {"values": [15, 30]},渲染后就会出错。
正确的模板(确保输出数组):
"minute": [{{ minute_values | join(', ') }}]
其中 minute_values 是一个数组变量,如 [15, 30, 45]。
修复方式四:使用 Dev Tools 验证完整配置 #
在 Kibana Dev Tools 中验证一个完整的 Watch 配置:
PUT _watcher/watch/my_watch
{
"trigger": {
"schedule": {
"minute": [0, 15, 30, 45],
"hour": "*"
}
},
"input": {
"search": {
"request": {
"indices": ["my-index"],
"body": {
"query": { "match_all": {} }
}
}
}
},
"condition": {
"compare": {
"ctx.payload.hits.total": { "gt": 0 }
}
},
"actions": {
"log": {
"logging": {
"text": "Found {{ctx.payload.hits.total}} hits"
}
}
}
}
提交后确认返回 "acknowledged": true,再通过以下命令验证 Watch 状态:
GET _watcher/watch/my_watch/_status
后续注意事项与推荐建议 #
- 在 CI/CD 流程中加入 Watch JSON 的 schema 校验步骤,在提交前就发现格式问题,避免将错误配置推到生产环境。
- 对于复杂的定时需求,优先考虑使用
cron表达式而非单独的minute/hour/day字段组合,可读性和维护性更好。 - 建立 Watch 配置的版本管理机制,每次变更都有 diff 记录,便于快速回滚到上一个可用版本。
- 在测试环境充分验证 Watch 配置后再应用到生产,尤其注意
minute值范围是 0-59,超出范围会触发另一个异常(可参考相关错误链接)。
借助 INFINI 产品提升排障效率 #
- INFINI Console 适合查看集群健康度、节点指标、索引状态,并可通过其界面化管理能力辅助观察 Watcher 执行情况,帮助快速判断定时任务是否按预期触发。
- INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测、限流和流量治理,可以在 Watcher 触发大量操作时提供额外的可观测性支持,避免批量操作对集群造成冲击。
- 建议将 Watch 执行日志、失败记录和变更历史统一接入监控面板,缩短从"发现定时任务未执行"到"定位配置错误"的时间。
5. 小结 #
invalid time minute value. expected string/number value or an array of string/number values 这个错误的根因非常明确:Watcher schedule 中 minute 字段的顶层结构不符合解析器的预期。修复的核心思路是:
- 确认
minute字段是单个数值/字符串,或是由数值/字符串组成的数组; - 不要将
minute本身定义为对象; - 如果需求是 cron 表达式,应使用
cron字段而非minute字段。
只要遵循 Watcher 调度配置的正确 JSON 结构,并在模板生成或动态配置场景中做好输出校验,这类问题完全可以提前规避。对于已经出现的错误,结合完整的报错 token 信息和 Watch 配置,通常可以在几分钟内定位并修复。
相关错误 #
附:日志上下文 #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
} else {
throw new ElasticsearchParseException("invalid time minute value. expected string/number value or an array of " +
"string/number values; but found [{}]", token);
}





