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

AWS CLI S3 cp命令报HeadObject 403 Forbidden错误排查

问题现象

需要执行的两条AWS S3 CLI命令:

  • 递归列出存储桶内容:aws s3 ls s3://my-bucket/ --recursive
  • 下载密钥文件到本地:aws s3 cp s3://my-bucket/ec2_keypair.pem ec2_keypair.pem

不同环境执行表现存在差异:

  • 个人笔记本:两条命令均运行正常,可正确列出目标存储桶内文件,也可正常下载目标密钥文件
  • Linux虚拟机:第一条ls命令可正常返回存储桶文件列表,第二条cp命令执行时报错:fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden

两个环境配置文件中aws_access_key_id、aws_secret_access_key、default.region三项配置完全一致,尝试多种常规方案未解决,补充--debug参数执行cp命令的末尾日志如下:

2022-06-13 08:49:26,151 - MainThread - botocore.parsers - DEBUG - Response body:

2022-06-13 08:49:26,155 - MainThread - botocore.hooks - DEBUG - Event needs-retry.s3.HeadObject: calling handler <botocore.retryhandler.RetryHandler object at 0x7fe5ad1fa8d0>
2022-06-13 08:49:26,155 - MainThread - botocore.retryhandler - DEBUG - No retry needed.
2022-06-13 08:49:26,155 - MainThread - botocore.hooks - DEBUG - Event needs-retry.s3.HeadObject: calling handler <bound method S3RegionRedirector.redirect_from_error of <botocore.utils.S3RegionRedirector object at 0x7fe5ad1fa950>>
2022-06-13 08:49:26,155 - MainThread - botocore.hooks - DEBUG - Event after-call.s3.HeadObject: calling handler <function enhance_error_msg at 0x7fe5ae0b3bd0>
2022-06-13 08:49:26,156 - MainThread - awscli.customizations.s3.results - DEBUG - Exception caught during command execution: An error occurred (403) when calling the HeadObject operation: Forbidden
Traceback (most recent call last):
  File "/opt/circleci/.pyenv/versions/2.7.18/lib/python2.7/site-packages/awscli/customizations/s3/s3handler.py", line 173, in call
    for fileinfo in fileinfos:
  File "/opt/circleci/.pyenv/versions/2.7.18/lib/python2.7/site-packages/awscli/customizations/s3/fileinfobuilder.py", line 31, in call
    for file_base in files:
  File "/opt/circleci/.pyenv/versions/2.7.18/lib/python2.7/site-packages/awscli/customizations/s3/filegenerator.py", line 142, in call
    for src_path, extra_information in file_iterator:
  File "/opt/circleci/.pyenv/versions/2.7.18/lib/python2.7/site-packages/awscli/customizations/s3/filegenerator.py", line 318, in list_objects
    yield self._list_single_object(s3_path)
  File "/opt/circleci/.pyenv/versions/2.7.18/lib/python2.7/site-packages/awscli/customizations/s3/filegenerator.py", line 355, in _list_single_object
    response = self._client.head_object(**params)
  File "/opt/circleci/.pyenv/versions/2.7.18/lib/python2.7/site-packages/botocore/client.py", line 386, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/opt/circleci/.pyenv/versions/2.7.18/lib/python2.7/site-packages/botocore/client.py", line 705, in _make_api_call
    raise error_class(parsed_response, operation_name)
ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
2022-06-13 08:49:26,157 - Thread-1 - awscli.customizations.s3.results - DEBUG - Shutdown request received in result processing thread, shutting down result thread.
排查思路与解决方案

先明确权限逻辑差异:aws s3 ls调用的是桶级ListBucket接口,仅需要存储桶维度的s3:ListBucket权限;aws s3 cp下载单个对象前会先调用HeadObject接口获取对象元数据,这一步需要对象维度的s3:GetObject权限,403报错即该接口权限校验未通过。结合两边配置文件一致但表现不同的特征,按以下优先级排查:

  • 第一步确认实际生效的凭证:不要只核对静态配置文件内容,在Linux虚拟机上执行aws configure list,查看当前CLI实际加载的凭证来源、区域配置,排查是否存在AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN、AWS_PROFILE等环境变量覆盖了配置文件的凭证,这类环境变量优先级高于配置文件,是最常见的“配置看起来一致实际加载不同”的原因。
  • 第二步升级CLI版本:从debug日志的路径可以看出,Linux虚拟机上的AWS CLI运行在Python 2.7环境上,属于非常老旧的版本,老版本CLI存在S3 SigV4签名逻辑bug、虚拟主机寻址兼容问题,对S3新的加密、访问点特性支持不全,很容易出现签名校验失败触发403,直接升级到最新稳定版AWS CLI后重试即可,个人笔记本上的CLI一般版本较新,不会触发这类问题。
  • 第三步检查对象加密与权限边界:如果ec2_keypair.pem使用AWS KMS客户管理密钥(CMK)加密,除了S3的s3:GetObject权限,还需要对应KMS密钥的kms:Decrypt权限;如果对象是其他AWS账号上传到该存储桶,还需要确认桶策略是否授予了当前身份对该跨账号对象的读权限,这类对象级权限限制不会影响ListBucket接口,只会在访问具体对象时报错。
  • 第四步检查网络出口与策略限制:如果Linux虚拟机走企业代理、固定NAT网关出口,需要确认S3桶策略、组织SCP策略是否对源IP做了权限限制——很多场景下管理员会放开ListBucket的IP限制,但对GetObject/HeadObject接口做严格的源IP校验,会出现ls能通、下载报错的情况。
  • 第五步通过CloudTrail定位精确拒绝原因:如果以上步骤都没解决,执行aws s3api head-object --bucket my-bucket --key ec2_keypair.pem拿到请求的RequestId,在AWS CloudTrail中查找对应事件,事件记录会明确标注是IAM身份策略、桶策略、KMS策略、SCP策略还是资源策略拒绝了请求,以及对应的策略语句ID,可直接定位根因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 15:39:17