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

适用版本: 7.4-8.17

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

you must not specify both region and endpoint 是 Elasticsearch 在执行 S3 快照仓库的 cleanup 操作时抛出的参数校验异常。该错误表示在仓库配置中同时指定了 regionendpoint 两个互斥参数,Elasticsearch 无法判断应优先采用哪种服务定位方式,因此在参数校验阶段直接拒绝请求。

常见现象 #

  • 执行 POST /_snapshot/<repo>/_cleanup 时立即返回 400 错误,请求尚未真正发送到 S3。
  • 日志中不会先出现网络错误(如连接超时、DNS 解析失败等),因为请求在参数校验阶段就被拦截。
  • 常见于同一套 Infrastructure as Code 模板、Terraform 配置或 Ansible Playbook 同时兼容 AWS S3 和自建 S3 兼容存储(MinIO、Ceph RGW、金山云 KS3、阿里云 OSS S3 兼容模式等),结果两个参数被同时带入。
  • 如果在 Kibana / INFINI Console 中通过界面配置仓库,也可能因为勾选了"自定义端点"同时保留了区域字段而触发此错误。

典型报错与异常栈 #

ElasticsearchException: you must not specify both region and endpoint

完整异常栈通常类似:

ElasticsearchException: you must not specify both region and endpoint
    at org.elasticsearch.common.blobstore.BlobStoreException.mergeOptions(BlobStoreUtils.java:XX)
    at org.elasticsearch.repositories.s3.S3Service.createClient(S3Service.java:XX)
    at org.elasticsearch.repositories.s3.S3Repository.performCleanup(S3Repository.java:XX)
    at org.elasticsearch.action.admin.cluster.snapshots.cleanup.TransportCleanupSnapshotAction.masterOperation(...)

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

regionendpoint 是 Elasticsearch S3 插件中两种互斥的服务定位方式,二者分别对应不同的使用场景:

参数用途适用场景
region指定 AWS S3 的标准区域(如 us-east-1cn-north-1使用 AWS 官方 S3 服务
endpoint指定自定义 S3 兼容服务的访问地址使用 MinIO、Ceph、第三方 S3 兼容存储

为什么不能同时指定?

  • 当指定 region 时,AWS SDK 会自动根据区域构造对应的标准 S3 端点(如 s3.us-east-1.amazonaws.com),无需也不应再手动指定 endpoint
  • 当指定 endpoint 时,SDK 会直接向该自定义地址发送请求,此时 region 信息已隐含在 endpoint URL 中(或由 S3 兼容服务自行处理),再指定 region 反而可能导致 SDK 尝试拼接标准 AWS 端点,造成请求路由混乱。
  • Elasticsearch 的 S3 仓库插件在 cleanup 操作的参数校验逻辑中显式禁止了这种冲突组合,以防止产生不可预测的行为。

常见触发场景 #

  1. 配置模板未区分存储类型:Terraform / Ansible 模板中将所有 S3 相关参数全都暴露,导致 AWS S3 和 MinIO 共用同一份参数。
  2. 从 AWS S3 迁移到 MinIO 时残留配置:将仓库从 AWS S3 迁移到自建 MinIO 后,只修改了 endpoint 但未清除 region
  3. 手动配置时误勾选:在 Kibana / INFINI Console 的仓库管理界面中,勾选自定义端点后忘记清空区域字段。
  4. 多环境配置合并错误:开发环境用 MinIO(endpoint)、生产环境用 AWS S3(region),合并配置时两个条件分支同时生效。

3. 如何排查这个异常 #

建议按以下步骤定位问题:

  1. 获取完整报错信息:记录报错时间、仓库名称、执行的操作(_cleanup)以及完整的异常栈。
  2. 检查仓库当前配置:执行以下命令查看仓库的完整设置:
    GET /_snapshot/<repo_name>
    
  3. 确认仓库类型:检查 type 字段是否为 s3
  4. 检查冲突参数:在返回的 settings 中确认是否同时存在 regionendpoint
  5. 确认目标存储类型:根据 endpoint 的值判断实际使用的是 AWS S3 还是 S3 兼容服务,以决定保留哪个参数。
  6. 检查配置来源:如果仓库是通过 Terraform、Ansible 或其他自动化工具创建的,检查模板中是否存在条件分支同时为真的情况。

排查时需要注意的问题 #

  • regionendpoint 可能来自不同层级:仓库自身设置、Elasticsearch 节点配置(elasticsearch.yml 中的 s3.client.default.region 等)、以及插件默认值。需要逐层确认参数来源。
  • 某些 S3 兼容服务(如阿里云 OSS S3 兼容模式)虽然支持 endpoint,但也可能接受 region 参数,此时应优先遵循服务商的官方建议,而非同时指定两者。

4. 如何解决这个错误 #

场景一:目标是 AWS S3(保留 region,删除 endpoint#

如果确认仓库使用的是 AWS 官方 S3 服务,应保留 region,删除 endpoint

# 先查看当前配置
GET /_snapshot/my_s3_repo

# 使用正确的配置更新仓库(只保留 region)
PUT /_snapshot/my_s3_repo
{
  "type": "s3",
  "settings": {
    "bucket": "my-es-snapshots",
    "region": "us-east-1",
    "base_path": "snapshots"
  }
}

场景二:目标是 S3 兼容存储(保留 endpoint,删除 region#

如果使用的是 MinIO、Ceph RGW 或其他 S3 兼容服务,应保留 endpoint,删除 region

# MinIO 示例
PUT /_snapshot/my_minio_repo
{
  "type": "s3",
  "settings": {
    "bucket": "elasticsearch-snapshots",
    "endpoint": "http://minio.example.com:9000",
    "access_key": "minioadmin",
    "secret_key": "minioadmin",
    "base_path": "snapshots"
  }
}

# Ceph RGW 示例
PUT /_snapshot/my_ceph_repo
{
  "type": "s3",
  "settings": {
    "bucket": "es-backups",
    "endpoint": "https://ceph-rgw.example.com",
    "access_key": "CEPH_ACCESS_KEY",
    "secret_key": "CEPH_SECRET_KEY",
    "base_path": "es"
  }
}

场景三:通过 Terraform 管理仓库时的修复 #

如果使用 Terraform 管理 Elasticsearch 快照仓库,确保条件判断互斥:

variable "s3_endpoint" {
  description = "S3 兼容服务的自定义端点,AWS S3 时留空"
  default     = ""
}

resource "elasticsearch_snapshot_repository" "s3" {
  name = "my_s3_repo"

  s3 {
    bucket     = "my-es-snapshots"
    region     = var.s3_endpoint == "" ? "us-east-1" : null
    endpoint   = var.s3_endpoint != "" ? var.s3_endpoint : null
    access_key = var.s3_access_key
    secret_key = var.s3_secret_key
    base_path  = "snapshots"
  }
}

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

  • 参数互斥校验:在自动化脚本或配置模板中,为 regionendpoint 增加互斥校验,确保二者不会同时出现。
  • 仓库配置定期审计:定期执行 GET /_snapshot/_all 检查所有仓库配置,及时发现异常组合。
  • 区分环境配置:为多环境(开发/测试/生产)分别维护独立的配置模板,避免跨环境参数污染。
  • 清理前验证参数:在执行 cleanup 之前,先在测试环境验证仓库配置的正确性,避免对生产快照数据造成风险。
  • 使用 INFINI Console 管理仓库:通过 INFINI Console 的快照仓库管理界面,可以避免手动配置参数时的疏忽,界面会自动根据选择的存储类型禁用冲突字段。

5. 小结 #

you must not specify both region and endpoint 的根因是 S3 快照仓库参数配置冲突:regionendpoint 是两种互斥的服务定位方式,分别对应 AWS S3 和 S3 兼容存储。解决方法是根据实际使用的存储类型,只保留其中一个参数。建议在配置模板中增加互斥校验,并定期审计仓库配置,防止类似问题在生产环境中出现。

相关错误 #

附:日志上下文 #

下面保留 Elasticsearch 源码中的校验逻辑,便于结合异常栈定位问题:

// 来自 Elasticsearch S3 仓库插件的校验逻辑
if (Strings.isNullOrEmpty(region) && Strings.isNullOrEmpty(endpoint)) {
    throw new ElasticsearchException("region or endpoint option is required for cleaning up S3 repository");
}
if (Strings.isNullOrEmpty(region) == false && Strings.isNullOrEmpty(endpoint) == false) {
    throw new ElasticsearchException("you must not specify both region and endpoint");
}