You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用boto3下载S3文件版本时遭遇NoSuchVersion错误求助

使用boto3下载S3对象版本时出现NoSuchVersion错误

我正尝试使用boto3(版本1.34.113)下载Amazon S3中某文件的所有版本,但持续报错:
botocore.exceptions.ClientError: An error occurred (NoSuchVersion) when calling the GetObject operation: The specified version does not exist.

我的Python代码如下:

import boto3

S3_BUCKET = "mybucket"
S3_KEY = "mykey"
s3_client = boto3.client("s3")
paginator = s3_client.get_paginator("list_object_versions")
page_iterator = paginator.paginate(Bucket=S3_BUCKET, Prefix=S3_KEY)
for page in page_iterator:
    for version_obj in page.get("Versions", []):
        version_details = s3_client.get_object(
            Bucket=S3_BUCKET, Key=S3_KEY, VersionId=version_obj["VersionId"]
        )

代码能够列出版本,但无法执行get_object操作。

我已进行的排查操作:

  • 拥有完整S3访问权限(s3:*权限作用于*资源)
  • 本地凭证配置正确
  • 可通过AWS控制台S3界面列出并下载版本
  • 仅部分文件存在此问题
  • S3键并非其他对象的前缀,排除键不匹配问题(list versions使用Prefix,get object使用Key)
  • AWS S3 CLI(版本aws-cli/2.15.43 Python/3.11.8 Linux/6.8.0-48-generic exe/x86_64.ubuntu.24 prompt/off)可正常执行aws s3api list-object-versions --bucket mybucket --prefix mykey和aws s3api get-object --bucket mybucket --key mykey --version-id versionidfromresponseabove outfile命令
  • 文件未被删除
  • 版本未被删除

解决方案

1. 使用版本对象自带的Key字段

问题大概率是硬编码的S3_KEY和版本对象实际存储的Key存在字符编码或细微差异(比如空格转义、特殊字符处理),直接使用version_obj["Key"]替代硬编码值即可:

import boto3

S3_BUCKET = "mybucket"
S3_KEY = "mykey"
s3_client = boto3.client("s3")
paginator = s3_client.get_paginator("list_object_versions")
page_iterator = paginator.paginate(Bucket=S3_BUCKET, Prefix=S3_KEY)
for page in page_iterator:
    for version_obj in page.get("Versions", []):
        # 使用版本对象自带的Key,避免字符匹配问题
        version_details = s3_client.get_object(
            Bucket=S3_BUCKET, Key=version_obj["Key"], VersionId=version_obj["VersionId"]
        )
        # 可添加保存文件逻辑:
        # with open(f"{version_obj['Key'].replace('/','_')}_{version_obj['VersionId']}", 'wb') as f:
        #     f.write(version_details['Body'].read())

2. 添加重试机制应对临时不可访问

如果是跨区域复制的版本同步延迟等临时问题,可添加指数退避的重试逻辑:

import boto3
from botocore.exceptions import ClientError
import time

def get_object_with_retry(s3_client, bucket, key, version_id, retries=3):
    for attempt in range(retries):
        try:
            return s3_client.get_object(Bucket=bucket, Key=key, VersionId=version_id)
        except ClientError as e:
            if e.response['Error']['Code'] == 'NoSuchVersion' and attempt < retries - 1:
                time.sleep(2 ** attempt)  # 指数退避等待
                continue
            raise

S3_BUCKET = "mybucket"
S3_KEY = "mykey"
s3_client = boto3.client("s3")
paginator = s3_client.get_paginator("list_object_versions")
page_iterator = paginator.paginate(Bucket=S3_BUCKET, Prefix=S3_KEY)
for page in page_iterator:
    for version_obj in page.get("Versions", []):
        version_details = get_object_with_retry(
            s3_client, S3_BUCKET, version_obj["Key"], version_obj["VersionId"]
        )

内容的提问来源于stack exchange,提问作者Samkit Jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:17:17