Skip to content

[BUG] 独立 S3 listener 在 storage 未就绪时错误返回 404/NoSuchKey #2795

Description

@nostalume

环境

  • OpenList: v4.2.3 (a92d59d)
  • Windows 10
  • 独立 S3 listener: :5246
  • storage: AliyundriveOpen, mount path /AliPan
  • S3 bucket mapping: AliBackup -> /AliPan/Backup

问题

独立 S3 listener 会在目标 storage 尚未完成异步加载时接收请求,并把内部的 storage-unavailable 错误转换为 S3 404 NotFound / NoSuchKey

这会让 S3 客户端错误地认为 repository 或 object 不存在;例如 backup clients 可能随后尝试初始化一个本不该初始化的 repository。

最小复现

  1. 启动 OpenList,使 S3 listener 监听 :5246

  2. /AliPan storage 完成初始化前,向已有对象发起 S3 HEAD,例如:

    HEAD /AliBackup/config
    
  3. 观察响应为 404

实际行为

日志中的内部原因是 storage 不可用,而不是对象不存在:

failed get storage: storage not found; rawPath: /AliPan/Backup/config
HEAD /AliBackup/config -> 404

同一 bucket mapping 和同一对象在 storage 已加载后返回 200,并且 keys/snapshots/index/data/ 都可正常列出。因此该 404 是错误映射。

源码线索

  • internal/bootstrap/storage.goLoadStorages() 在 goroutine 中异步加载 storage。
  • 主 HTTP router 使用 middlewares.StoragesLoaded
  • server/router.goInitS3(e) 仅调用 Cors(e)S3Server(e.Group("/")),没有相同的 readiness middleware。

期望行为

独立 S3 listener 应在 storage 尚未加载完毕时:

  • 等待 readiness;或
  • 返回明确的可重试服务错误(例如 HTTP 503 / S3 InternalError 或 ServiceUnavailable)。

它不应返回 NoSuchKey / 404,因为对象路径和 bucket mapping 都是正确的。

影响

restic、rustic 和其他 S3 client 会把 404 理解为 repository/object 缺失;这会导致错误的初始化或错误恢复流程。

Metadata

Metadata

Assignees

No one assigned

    Labels

    invalidInvalid Content/Cannot Reproduce

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions