使用Python+Boto3获取S3对象版本及元数据时遇412预条件失败错误
解决S3对象版本元数据获取时的412预条件失败问题
这个问题的核心是你误用了IfMatch参数——它的作用是校验当前对象的最新版本ETag,用来做并发更新时的一致性检查,完全不适合用来获取历史版本的元数据。你需要用每个版本对应的VersionId来指定要获取的具体版本,这才是正确的姿势!
为什么会报412错误?
当你第一次调用get_object时,可能刚好那个版本是当前最新版,IfMatch校验通过;但第二次迭代的是历史版本,它的ETag和当前最新版本的ETag不匹配,IfMatch的预条件就不满足了,自然返回412错误。哪怕你打印的ETag是有效的,但它不是当前最新版本的ETag,所以校验失败。
修正后的代码
直接用list_object_versions返回的VersionId参数来获取对应版本的元数据,代码如下:
import boto3 s3 = boto3.client('s3') response = s3.list_object_versions( Bucket='my-bucket', Prefix='file.exe' ) obj_versions = response["Versions"] # 循环处理每个版本 for obj_version in obj_versions: key = obj_version['Key'] version_id = obj_version['VersionId'] print(f"Processing version {version_id} of {key}") # 使用VersionId指定获取该版本的对象及元数据 obj_response = s3.get_object( Bucket='my-bucket', Key=key, VersionId=version_id ) # 提取自定义元数据x-amz-meta-version # 注意:boto3会自动去掉x-amz-meta-前缀,键名转为小写 custom_version = obj_response['Metadata'].get('version') print(f"Custom metadata x-amz-meta-version: {custom_version}")
补充说明
- 如果你的自定义元数据键名有大写字母(比如
x-amz-meta-Version),boto3返回的Metadata里的键会是全小写的version,所以用小写键名去获取即可。 - 如果你需要确认原始的HTTP响应头,可以通过
obj_response['ResponseMetadata']['HTTPHeaders']查看,里面会保留完整的x-amz-meta-version键名。
内容的提问来源于stack exchange,提问作者soyoh
相关产品推荐
相关产品推荐

