适用版本: 8.8-8.9
1. 错误异常的基本描述 #
A primary endpoint is required when setting a secondary endpoint 是 Elasticsearch 在配置 Azure Blob Storage 快照仓库(snapshot repository)时抛出的配置错误。当你为 Azure 仓库客户端设置 secondary_endpoint(辅助终结点)但没有同时设置 endpoint(主终结点)时,就会触发此错误。Azure 的 RA-GRS(读访问异地冗余存储)功能支持主辅终结点,但辅助终结点必须依附于主终结点存在,不能单独定义。
常见现象 #
- Elasticsearch 返回 HTTP
400 Bad Request状态码,响应体中包含SettingsException。 - 创建或更新 Azure 快照仓库的请求(
PUT _snapshot/<repo_name>)失败。 - 在 Elasticsearch 服务端日志中会记录详细的异常信息。
- 如果是通过自动化脚本或 Terraform 配置仓库,会在客户端收到异常响应。
- 仓库无法创建,导致后续的快照备份任务失败。
典型报错与异常栈 #
该异常的典型日志形态如下:
SettingsException: A primary endpoint is required when setting a secondary endpoint
at org.elasticsearch.repositories.azure.AzureStorageSettings.laod(AzureStorageSettings.java:...)
at org.elasticsearch.repositories.azure.AzureRepositoryPlugin.lambda$getClientSettings$0(AzureRepositoryPlugin.java:...)
at org.elasticsearch.common.settings.Setting$GroupSetting.lambda$getConcreteSetting$0(Setting.java:...)
通过 API 请求的响应通常如下:
{
"error": {
"root_cause": [
{
"type": "settings_exception",
"reason": "A primary endpoint is required when setting a secondary endpoint"
}
],
"type": "settings_exception",
"reason": "A primary endpoint is required when setting a secondary endpoint"
},
"status": 400
}
2. 为什么会发生这个错误 #
Elasticsearch 的 Azure Blob Storage 仓库插件支持 Azure 的 RA-GRS 冗余策略,允许配置主终结点(endpoint)和辅助终结点(secondary_endpoint)。源码中的逻辑是:
if (hasEndpoint == false && hasSecondaryEndpoint) {
throw new SettingsException("A primary endpoint is required when setting a secondary endpoint");
}
这意味着 secondary_endpoint 只是 endpoint 的补充,不能单独定义。常见原因包括:
- 只配置了辅助终结点:运维人员只填写了
secondary_endpoint,忘记了配置endpoint。 - 从标准 endpoint 迁移时遗漏:从标准 Azure endpoint 规则改为显式 endpoint 时,只迁移了
secondary_endpoint。 - 模板变量缺失:使用 Terraform 或 Ansible 等工具时,模板变量缺失导致
endpoint渲染后为空。 - 配置文件复制错误:从其他仓库配置复制时,可能只复制了部分配置。
- 环境差异:在不同环境(开发、测试、生产)之间迁移配置时,遗漏了
endpoint。
3. 如何排查和解决这个异常和解决这个异常 #
排查步骤 #
建议按以下顺序进行排查:
第一步:查看完整的错误响应和仓库配置 #
# 重现错误并查看完整响应
curl -X PUT "localhost:9200/_snapshot/my_azure_repo" -H 'Content-Type: application/json' -d @repo.json 2>&1 | jq .
# 查看 Elasticsearch 日志中的详细错误
tail -n 200 /var/log/elasticsearch/elasticsearch.log | grep -A 20 "A primary endpoint is required"
第二步:检查仓库配置中的 endpoint 设置 #
# 查看现有仓库配置
curl -X GET "localhost:9200/_snapshot/my_azure_repo?pretty"
# 检查是否配置了 secondary_endpoint 但缺少 endpoint
cat repo.json | jq '.settings'
第三步:验证正确的 Azure 仓库配置 #
// 错误示例:只有 secondary_endpoint
{
"type": "azure",
"settings": {
"secondary_endpoint": "https://mystorage-secondary.blob.core.windows.net",
// 错误:缺少 endpoint
}
}
// 正确示例:同时配置 endpoint 和 secondary_endpoint
{
"type": "azure",
"settings": {
"endpoint": "https://mystorage.blob.core.windows.net",
"secondary_endpoint": "https://mystorage-secondary.blob.core.windows.net"
}
}
// 正确示例:只使用主 endpoint(如果不需要辅助终结点)
{
"type": "azure",
"settings": {
"endpoint": "https://mystorage.blob.core.windows.net"
// 不配置 secondary_endpoint
}
}
第四步:在测试环境验证 #
# 在测试环境创建 Azure 仓库
curl -X PUT "localhost:9200/_snapshot/test_azure_repo" -H 'Content-Type: application/json' -d '
{
"type": "azure",
"settings": {
"endpoint": "https://mystorage.blob.core.windows.net",
"secondary_endpoint": "https://mystorage-secondary.blob.core.windows.net",
"container": "my-container",
"base_path": "/backups"
}
}'
# 验证仓库是否工作
curl -X PUT "localhost:9200/_snapshot/test_azure_repo/_verify?pretty"
排查时需要注意的问题 #
- 检查所有 Azure 客户端配置:如果定义了多个 Azure 客户端,确保出错的那个配置正确。
- 注意 endpoint_suffix:如果配置了
endpoint_suffix,通常不应再手工设置secondary_endpoint,两者可能冲突。 - 确认仓库类型:确保你配置的是 Azure Blob Storage 仓库,不是 S3 或 GCS。
- 区分环境:不同环境(开发、测试、生产)的 endpoint 可能不同,确认使用的是正确的环境配置。
4. 如何解决这个错误 #
常用修复思路 #
方案一:补齐 primary endpoint(推荐) #
# 更新仓库配置,添加缺失的 endpoint
curl -X PUT "localhost:9200/_snapshot/my_azure_repo" -H 'Content-Type: application/json' -d '
{
"type": "azure",
"settings": {
"endpoint": "https://mystorage.blob.core.windows.net",
"secondary_endpoint": "https://mystorage-secondary.blob.core.windows.net",
"container": "my-container",
"base_path": "/backups"
}
}'
方案二:如果不需要辅助终结点,直接移除 secondary_endpoint #
# 如果不需要 RA-GRS 的辅助终结点,移除它
curl -X PUT "localhost:9200/_snapshot/my_azure_repo" -H 'Content-Type: application/json' -d '
{
"type": "azure",
"settings": {
"endpoint": "https://mystorage.blob.core.windows.net",
"container": "my-container",
"base_path": "/backups"
}
}'
方案三:使用 endpoint_suffix 代替手工 endpoint #
# 使用 Azure 标准 endpoint suffix,不需要手工设置 endpoint
curl -X PUT "localhost:9200/_snapshot/my_azure_repo" -H 'Content-Type: application/json' -d '
{
"type": "azure",
"settings": {
"account": "mystorage",
"endpoint_suffix": "core.windows.net",
"container": "my-container",
"base_path": "/backups"
}
}'
方案四:在 Terraform 或 Ansible 中修复 #
# Terraform 示例:确保 endpoint 和 secondary_endpoint 同时存在
resource "elasticsearch_snapshot_repository" "azure_repo" {
name = "my_azure_repo"
type = "azure"
settings = {
endpoint = "https://mystorage.blob.core.windows.net"
secondary_endpoint = "https://mystorage-secondary.blob.core.windows.net"
container = "my-container"
base_path = "/backups"
}
}
后续注意事项与推荐建议 #
- 建立仓库配置规范:为团队制定 Azure 仓库配置的规范,明确
endpoint是必填项,secondary_endpoint是选填项且依赖于endpoint。 - 在 CI/CD 中加入校验:对于仓库配置,在部署前进行结构校验,确保
secondary_endpoint出现时一定有对应的endpoint。 - 使用变量管理配置:在 Terraform、Ansible 或 Helm 中,使用变量来管理 endpoint 配置,避免硬编码。
- 监控仓库状态:通过 Elasticsearch 的仓库验证 API 和监控工具,及时发现配置问题。
- 参考 Azure 文档:在配置 Azure 仓库前,先查阅 Azure 官方文档,确认 endpoint 格式和冗余策略。
借助 INFINI 产品提升排障效率 #
INFINI Console 提供快照仓库的可视化管理界面,可以直观地查看、编辑和验证 Azure 仓库配置。通过 Console 的仓库管理功能,可以快速发现缺少
endpoint的配置,并直接编辑修复。INFINI Gateway 可以作为 Elasticsearch API 的代理层,在仓库创建请求到达 Elasticsearch 之前进行拦截和检查。Gateway 可以自动检测缺少
endpoint的配置,并根据预定义的策略进行处理(如自动补齐、拒绝请求、告警通知等)。对于依赖 Azure Blob Storage 进行快照备份的团队,建议结合 INFINI Console 的仓库管理功能和 INFINI Gateway 的请求治理能力,建立从仓库配置、验证、监控到告警的完整流程,减少因配置错误导致的备份失败。
5. 小结 #
A primary endpoint is required when setting a secondary endpoint 是一个典型的 Azure 仓库配置错误,根源在于 secondary_endpoint 不能脱离 endpoint 单独存在。虽然报错信息直接指向配置关系不完整,但解决思路很简单:要么补齐 endpoint,要么移除 secondary_endpoint。
在实际工作中,为避免此类问题,建议在开发阶段使用 INFINI Console 的可视化工具来构造和验证仓库配置,在 CI/CD 流程中加入配置校验,并使用 INFINI Gateway 作为防护层来拦截错误的配置请求。
相关错误 #
- both-an-endpoint-suffix-as-well-as-a-primary-endpoint-were-set:同时设置了endpoint_suffix和primary endpoint
- both-an-endpoint-suffix-as-well-as-a-secondary-endpoint-were-set:同时设置了endpoint_suffix和secondary endpoint
- invalid-azure-client-settings-with-name-clientname:无效的Azure客户端设置
- settings-exception:设置异常
- repository-exception:仓库异常
参考文档 #
- Elasticsearch Azure Blob Storage Repository 官方文档
- Azure Blob Storage RA-GRS 官方文档
- INFINI Console 文档
- INFINI Gateway 文档
附:日志上下文 #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
if (hasEndpointSuffix && hasSecondaryEndpoint) {
throw new SettingsException("Both an endpoint suffix as well as a secondary endpoint were set");
} else if (hasEndpoint == false && hasSecondaryEndpoint) {
throw new SettingsException("A primary endpoint is required when setting a secondary endpoint");
}
if (hasEndpointSuffix) {
connectionStringBuilder.append(";EndpointSuffix=").append(endpointSuffix);
}





