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

创建IAM用户Access Key后调用S3 putObject提示密钥不存在

问题:新生成的IAM Access Key调用S3 putObject时提示密钥不存在

为拥有S3对象写入权限的IAM用户创建Access Key后,立即用该密钥调用S3的putObject方法上传对象,执行时出现错误:

the aws access key id you provided does not exist in our records
代码明确使用刚生成的凭据,但认证失败。相关代码如下:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.CreateAccessKeyRequest;
import software.amazon.awssdk.services.iam.model.CreateAccessKeyResponse;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;

public static String[] creds() {
    IamClient fiddler = IamClient.builder().region(Region.AWS_GLOBAL).
            credentialsProvider(
                    StaticCredentialsProvider.create(
                            AwsBasicCredentials.create(
                                    "Access Key",
                                    "Secret Key")))
            .build();

    CreateAccessKeyResponse cakr = fiddler.createAccessKey(
            CreateAccessKeyRequest.builder().
                    userName("user").build());

    return new String[] {cakr.accessKey().accessKeyId(), cakr.accessKey().secretAccessKey()};
}

String[] cakr = creds();

S3Client iamUser = S3Client.builder().region(Region.AWS_GLOBAL).
        credentialsProvider(
                StaticCredentialsProvider.create(
                        AwsBasicCredentials.builder().
                                accessKeyId(cakr[0]).
                                secretAccessKey(cakr[1]).build()))
        .build();

File keyFile = new File(System.getProperty(
        "java.io.tmpdir"), "why" + ".key");

try (FileOutputStream writer = new FileOutputStream(
        keyFile)) {
    writer.write("why".getBytes());
} catch (IOException ex) {
    ex.printStackTrace();
}

iamUser.putObject(PutObjectRequest.builder()
                .bucket("bucket").
                key("pkeys/" + "why" + ".key").build(),
        keyFile.toPath());

核心原因

AWS IAM Access Key创建后存在全局同步延迟,刚生成的密钥不会立即在所有AWS服务端点生效,尤其是S3这类跨区域服务,同步耗时从几秒到几分钟不等。代码在生成密钥后立刻调用S3接口,此时密钥还未同步到S3的认证系统,因此触发密钥不存在的错误。

解决方案

1. 添加同步等待逻辑

在生成Access Key后,增加一段等待时间,确保密钥完成全局同步:

String[] cakr = creds();
// 等待30秒,可根据实际情况调整时长
Thread.sleep(30000);

2. 修正S3客户端的区域配置

S3服务不支持Region.AWS_GLOBAL,必须指定与目标桶一致的具体区域(比如Region.US_EAST_1),错误的区域配置会加剧同步延迟或导致认证失败:

S3Client iamUser = S3Client.builder()
        .region(Region.US_EAST_1) // 替换为你的S3桶所在区域
        .credentialsProvider(
                StaticCredentialsProvider.create(
                        AwsBasicCredentials.builder()
                                .accessKeyId(cakr[0])
                                .secretAccessKey(cakr[1])
                                .build()))
        .build();

3. 可选:验证密钥激活状态

如果等待后仍失败,可先调用IAM接口验证密钥是否已激活,确认后再调用S3:

// 等待后添加验证逻辑
IamClient verifyClient = IamClient.builder()
        .region(Region.AWS_GLOBAL)
        .credentialsProvider(StaticCredentialsProvider.create(
                AwsBasicCredentials.create("你的管理Access Key", "你的管理Secret Key")))
        .build();

// 调用该接口确认密钥已存在并可被查询
verifyClient.getAccessKeyLastUsed(GetAccessKeyLastUsedRequest.builder()
        .accessKeyId(cakr[0])
        .build());

额外检查项

  • 确认用于创建Access Key的父凭据拥有iam:CreateAccessKey权限,且目标IAM用户存在。
  • 检查S3桶的权限策略,确保目标IAM用户拥有s3:PutObject权限,且桶策略未拒绝该用户的请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 21:07:25