适用版本: 7.17-8.9
1. 错误异常的基本描述 #
Setting [RealmSettings.getFullSettingKey(..., setting.getClaim())] is required 表示当前安全 realm 的某个 claim 配置项被标记为必填,但在实际配置中未找到对应的值。Elasticsearch 在加载 realm 配置时会校验必填项,一旦发现缺失便立即抛出 SettingsException,阻止该 realm 生效。
常见现象 #
- 节点启动日志中出现
SettingsException,并明确指出缺失的 setting key,例如xpack.security.authc.realms.oidc.my_oidc.claims.principal。 - 对应 realm 无法加载,相关认证方式(如 OIDC、JWT、SAML)不可用,用户无法通过该方式登录。
- Kibana 或应用侧使用对应 realm 登录时返回
401 Unauthorized或500内部错误。 - 若多个 realm 中某一个配置有误,其他 realm 可能仍可正常工作,但日志中会持续报错。
典型报错与异常栈 #
SettingsException: Setting [xpack.security.authc.realms.oidc.oidc1.claims.principal] is required
at org.elasticsearch.xpack.security.authc.RealmSettings.getFullSettingKey(RealmSettings.java)
at org.elasticsearch.xpack.security.authc.oidc.OpenIdConnectRealmSettings.validate(OpenIdConnectRealmSettings.java)
at org.elasticsearch.xpack.security.authc.Realms.validateRealmSettings(Realms.java)
2. 为什么会发生这个错误 #
Elasticsearch 的安全 realm 配置中,某些 claim 映射(如 principal、groups、name、email)被设计为必填项。当 realm 类型为 OIDC、JWT 或 SAML 时,Elasticsearch 需要从身份提供者(IdP)返回的 token 或用户信息中提取这些字段,用于构建 Elasticsearch 内部用户身份。
常见原因包括:
- claims 配置块缺失:在 OIDC/JWT realm 配置中未配置
claims.principal、claims.groups等必填项。 - 配置项拼写错误:setting key 写错,例如
claim.principal而非claims.principal,或 realm 名称前缀不匹配。 - 复制配置未修改:从其他 realm 配置复制后未更新 realm 名称,导致配置项与实际 realm 不匹配。
- 版本升级引入新要求:升级 Elasticsearch 后,新版本对 claim 配置增加了必填校验,旧配置不再满足要求。
- 模板渲染为空:使用配置管理工具(如 Ansible、Terraform)渲染配置时,claim 相关变量为空,导致最终配置文件中缺少对应行。
3. 如何排查这个异常 #
建议按以下步骤逐一排查:
- 从报错信息中提取完整的 setting key,例如
xpack.security.authc.realms.oidc.my_oidc.claims.principal,确定缺失的具体配置项。 - 确认 realm 类型与名称,检查
elasticsearch.yml中对应 realm 的配置块,确认类型(oidc、jwt、saml)和名称是否一致。 - 检查 claims 配置块是否完整,对照官方文档确认当前 realm 类型要求哪些必填 claim。
- 验证配置语法,确保 YAML 缩进正确,配置项没有被注释掉,且没有多余的符号。
- 动态安全配置场景:如果使用
elasticsearch-service-tokens或 Kibana 中的安全配置,确认不在静态配置文件中遗漏了对应项。
排查时需要注意的问题 #
- 静态配置文件(
elasticsearch.yml)修改后需要重启节点才能生效,而动态安全配置无需重启但需要在对应 API 中正确设置。 - OIDC realm 的
claims.principal通常映射到 IdP 返回的sub或email字段,需与 IdP 实际返回的 claim 名称一致。 - 如果同时配置了多个 realm,建议逐个验证,避免因为一个 realm 的错误影响对其他 realm 的排查判断。
4. 如何解决这个错误 #
OIDC Realm 示例 #
OIDC realm 至少需要配置 claims.principal,通常还需要 claims.groups 用于角色映射:
xpack.security.authc.realms.oidc.oidc1:
order: 1
rp.client_id: "my-client-id"
rp.response_type: "code"
rp.redirect_uri: "https://kibana.example.com:5601/api/security/oidc/callback"
op.issuer: "https://keycloak.example.com/realms/my-realm"
op.authorization_endpoint: "https://keycloak.example.com/realms/my-realm/protocol/openid-connect/auth"
op.token_endpoint: "https://keycloak.example.com/realms/my-realm/protocol/openid-connect/token"
op.jwkset_path: "https://keycloak.example.com/realms/my-realm/protocol/openid-connect/certs"
claims.principal: "sub"
claims.groups: "groups"
claims.name: "name"
claims.email: "email"
JWT Realm 示例 #
JWT realm 同样需要明确 claims.principal:
xpack.security.authc.realms.jwt.jwt1:
order: 2
enabled: true
client_authentication.type: "shared_key"
allowed_issuer: "my-jwt-issuer"
allowed_audiences: ["my-audience"]
allowed_signature_algorithms: ["RS256"]
jwk_set.path: "https://auth.example.com/.well-known/jwks.json"
claims.principal: "sub"
claims.groups: "roles"
常用修复思路 #
- 对照报错中的完整 setting key,在对应 realm 配置中补齐缺失的 claim 映射。
- 确认 claim 名称与 IdP 实际返回的 JWT/ID Token 中的字段名一致(区分大小写)。
- 如果是配置模板渲染问题,在模板中给必填 claim 设置默认值或添加校验逻辑。
- 升级 Elasticsearch 后,查阅对应版本的 Breaking Changes 文档,确认是否有新增的必填配置项。
5. 预防措施 #
- 版本升级前审查配置:升级前查阅目标版本的 Elasticsearch 安全配置变更说明,提前补齐可能新增的必填项。
- 使用配置校验工具:在 CI/CD 流程中加入配置文件校验步骤,提前发现缺失的必填项。
- 统一配置模板管理:将 realm 配置纳入版本控制,避免手动修改导致的遗漏或拼写错误。
- 监控节点启动日志:在节点重启或新增节点时,自动检查日志中是否出现
SettingsException,及时发现配置问题。 - 文档化 claim 映射关系:记录每个 realm 的 claim 映射与对应 IdP 的字段关系,便于后续维护和排查。
6. 小结 #
该异常的本质是 Elasticsearch 在加载安全 realm 配置时发现必填的 claim 映射缺失。修复的核心是:从报错信息中定位缺失的 setting key,然后在对应 realm 配置中补齐正确的 claim 映射。配置时需注意 claim 名称与 IdP 实际返回字段保持一致,且 YAML 语法正确。
借助 INFINI Console 可以集中查看各集群的安全配置状态与节点日志,快速定位配置不一致问题;INFINI Gateway 可在认证请求层面做观测与治理,帮助发现 token 解析或 claim 映射异常。
相关错误 #
附:日志上下文 #
.filter(Objects::nonNull)
.toList();
});
}
} else if (required) {
throw new SettingsException("Setting [" + RealmSettings.getFullSettingKey(realmConfig; setting.getClaim()) + "] is required");
} else if (realmConfig.hasSetting(setting.getPattern())) {
throw new SettingsException(
"Setting ["
+ RealmSettings.getFullSettingKey(realmConfig; setting.getPattern())
+ "] cannot be set unless ["





