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

适用版本: 7.17-8.9

1. 错误异常的基本描述 #

The configuration setting [<setting_key>] is required 是 Elasticsearch 安全模块在初始化认证 realm 时抛出的 SettingsException。该异常明确表示:某个 realm 的必填配置项虽然被读取到了,但其值为空字符串,因此被视为未配置,导致该 realm 无法完成初始化,节点启动或安全配置重载失败。

常见现象 #

  • 节点启动失败,日志中出现 SettingsException: The configuration setting [...] is required
  • 仅影响某一个特定的 realm(例如 oidc_realmjwt_realmkerberos_realm),其余 realm 正常加载。
  • Elasticsearch 日志中会给出完整的 setting key,格式通常为 <realm_type>.<realm_name>.<setting_name>,可直接定位到缺失的配置项。
  • 如果是在动态更新安全配置时触发,可能导致安全配置更新失败,但不影响已运行的 realm。

典型报错与异常栈 #

SettingsException: The configuration setting [xpack.security.authc.realms.oidc.oidc1.client_id] is required
    at org.elasticsearch.xpack.security.authc.RealmSettings.require(RealmSettings.java)
    at org.elasticsearch.xpack.security.authc.oidc.OpenIdConnectRealmSettings$3.get(OpenIdConnectRealmSettings.java)
    ...

2. 为什么会发生这个错误 #

该异常的根本原因是:Elasticsearch 在 RealmSettings.require() 方法中读取配置值后,做了空字符串校验。如果 value.isEmpty()true,则直接抛出 SettingsException。这意味着问题不是"配置项不存在",而是"配置项存在但值为空"。

常见原因包括:

  • 配置模板渲染为空:使用 Helm、Ansible 或其他模板工具生成 elasticsearch.yml 时,变量未传入或为空,最终渲染出空字符串。
  • Keystore/Secret 为空:配置项引用了 secure settings(如 bin/elasticsearch-keystore add),但 keystore 中对应条目的值为空,或 Secret 挂载后文件内容为空。
  • 环境变量未设置:通过环境变量 ES_XPACK_SECURITY_AUTHC_REALMS_* 注入配置时,变量未赋值或赋值失败。
  • YAML 格式问题elasticsearch.yml 中配置项缩进错误,导致 Elasticsearch 将其解析为空值。
  • 复制粘贴遗漏:手动配置时复制了配置项 key 但没有填入实际值,例如 client_secret: 后面直接换行。

3. 如何排查和解决这个异常 #

建议按以下步骤排查:

  1. 定位具体 realm 和配置项:从异常信息中提取完整的 setting key,例如 xpack.security.authc.realms.oidc.oidc1.client_id,拆解出 realm 类型(oidc)、realm 名称(oidc1)和配置项名称(client_id)。
  2. 检查 elasticsearch.yml:直接查看配置文件,确认该配置项是否存在且值非空。注意 YAML 中冒号后必须有空格,值不能为空字符串。
  3. 检查 keystore:如果配置项使用了 secure settings,运行 bin/elasticsearch-keystore list 确认 key 存在,并通过 bin/elasticsearch-keystore show <key> 检查值是否为空。
  4. 检查模板渲染结果:如果使用 Helm 等工具部署,执行 helm template 或查看渲染后的 ConfigMap,确认配置值已正确注入。
  5. 检查 Secret 挂载:如果使用 Kubernetes Secret,确认 Secret 已创建且值非空,挂载路径正确,文件内容可读。
  6. 修复后验证:修改配置后,重启节点或通过 API 更新安全配置,观察节点日志确认 realm 初始化成功。

排查时需要注意的问题 #

  • 区分空字符串(key: ""key: 后无内容)和配置项不存在两种情况,前者触发此异常,后者通常会触发不同的报错。
  • Secure settings 的值无法通过 elasticsearch.yml 直接查看,必须通过 keystore 或运行时的节点 API 间接确认。
  • 如果多个 realm 同时配置失败,优先检查是否有全局的配置模板问题,而非逐个排查。

4. 如何解决这个错误 #

常用修复思路 #

  • 填入有效值:为报错的配置项填入非空且合法的值。以 OIDC realm 为例,常见必填项包括 client_idclient_secretop.issuerop.authorization_endpoint 等。
  • 在模板中增加空值校验:在 Helm values 或配置模板中,对必填项增加 required 校验,防止渲染出空字符串。例如 Helm 中可使用 required "client_id is required" .Values.oidc.clientId
  • 检查 YAML 格式:确保 elasticsearch.yml 中配置项正确缩进,冒号后有空格,且值不被引号或换行截断。
  • 重新设置 keystore:如果使用了 secure settings,重新执行 bin/elasticsearch-keystore add <key>,填入正确的值,然后重启节点。

常见 realm 类型的必填配置示例 #

OpenID Connect Realm:

xpack.security.authc.realms.oidc.oidc1:
  order: 1
  rp.client_id: "your-client-id"
  rp.client_secret: "your-client-secret"
  rp.response_type: "code"
  op.issuer: "https://accounts.google.com"
  op.authorization_endpoint: "https://accounts.google.com/o/oauth2/v2/auth"
  op.token_endpoint: "https://oauth2.googleapis.com/token"
  op.jwkset_path: "https://www.googleapis.com/oauth2/v3/certs"

JWT Realm:

xpack.security.authc.realms.jwt.jwt1:
  order: 2
  allowed_issuer: "your-issuer"
  allowed_audiences: ["your-audience"]
  jwk_set_path: "https://your-domain.com/.well-known/jwks.json"
  client_authentication.type: "shared_secret"

后续注意事项与推荐建议 #

  • 将 realm 配置纳入代码仓库管理,使用 CI/CD 在部署前校验必填配置项非空。
  • 对生产环境的 Secret 管理建立上线前检查流程,防止空 Secret 进入集群。
  • 在测试环境先验证 realm 配置,确认可以正常完成认证流程后再推送到生产环境。
  • 定期审查 elasticsearch.yml 和安全配置,及时清理不再使用的 realm,减少配置复杂度。

借助 INFINI 产品提升排障效率 #

  • INFINI Console 适合查看集群安全配置状态、节点日志和错误趋势,帮助快速判断 realm 初始化失败的影响范围。
  • INFINI Gateway 可以部署在 Elasticsearch 前面,对认证请求进行观测和治理,辅助定位认证链路中的问题。

5. 小结 #

The configuration setting [...] is required 异常的核心是"配置项值为空",而非"配置项不存在"。排查时应优先从异常信息中提取完整的 setting key,直接定位到具体的 realm 和配置项,然后检查配置文件、keystore 或模板渲染结果。修复后务必重启节点或重载安全配置,确认 realm 能正常初始化。

相关错误 #

附:日志上下文 #

下面保留当前页面中的源码片段,便于继续结合异常调用栈定位问题:

private static String require(RealmConfig config, Setting.AffixSetting setting) {
    final String value = config.getSetting(setting);
    if (value.isEmpty()) {
        throw new SettingsException("The configuration setting [" 
            + RealmSettings.getFullSettingKey(config, setting) + "] is required");
    }
    return value;
}