elunez/eladmin · error · BadRequestException

检查存储桶时出错: {}

Error message

检查存储桶时出错: {}

What it means

BadRequestException thrown from bucketExists(bucketName) when the S3 headBucket call fails with an S3Exception whose status is NOT 404 — i.e. the SDK reached S3 but the request was rejected (classic: 403 credentials wrong or no s3:ListBuckets/HeadBucket permission; also 301 wrong-region). The method deliberately returns false only for 404; every other failure bubbles up as this error with the AWS detail appended.

Source

Thrown at eladmin-tools/src/main/java/me/zhengjie/service/impl/S3StorageServiceImpl.java:231

     * 检查云存储桶是否存在
     * @param bucketName 存储桶名称
     */
    @SuppressWarnings({"all"})
    private boolean bucketExists(String bucketName) {
        try {
            HeadBucketRequest headBucketRequest = HeadBucketRequest.builder()
                    .bucket(bucketName)
                    .build();
            s3Client.headBucket(headBucketRequest);
            return true;
        } catch (S3Exception e) {
            // 如果状态码是 404 (Not Found), 说明存储桶不存在
            if (e.statusCode() == 404) {
                log.error("存储桶 '{}' 不存在。", bucketName);
                return false;
            }
            // 其他异常 (如 403 Forbidden) 说明存在问题,但不能断定它不存在
            throw new BadRequestException("检查存储桶时出错: " + e.awsErrorDetails().errorMessage());
        }
    }

    /**
     * 创建云存储桶
     * @param bucketName 存储桶名称
     */
    private boolean createBucket(String bucketName) {
        try {
            // 使用 S3Waiter 等待存储桶创建完成
            S3Waiter s3Waiter = s3Client.waiter();
            CreateBucketRequest bucketRequest = CreateBucketRequest.builder()
                    .bucket(bucketName)
                    .acl(BucketCannedACL.PRIVATE)
                    .build();
            s3Client.createBucket(bucketRequest);
            // 等待直到存储桶创建完成
            HeadBucketRequest bucketRequestWait = HeadBucketRequest.builder()

View on GitHub (pinned to 55fbf70595)

Solutions

  1. Check the appended AWS message: 'AccessDenied' -> fix credentials/permissions; 'PermanentRedirect'/'region' -> fix endpoint/region.
  2. Re-enter valid accessKey/secretKey in the S3 config and confirm the IAM user can head the bucket (aws s3api head-bucket --bucket <name>).
  3. Grant s3:ListBucket on the bucket (or s3:ListAllMyBuckets) plus s3:HeadBucket as needed.
  4. For MinIO/compatible stores, use the correct endpoint URL and path-style access in the client config.
  5. Verify server clock sync (signature v4 is time-sensitive).

Example fix

// before
catch (S3Exception e) {
    if (e.statusCode() == 404) {
        log.error("存储桶 '{}' 不存在。", bucketName);
        return false;
    }
    throw new BadRequestException("检查存储桶时出错: " + e.awsErrorDetails().errorMessage());
}

// after: name the likely cause by status code
catch (S3Exception e) {
    if (e.statusCode() == 404) {
        return false;
    }
    if (e.statusCode() == 403) {
        throw new BadRequestException("无权访问存储桶(凭证错误或缺少权限): " + e.awsErrorDetails().errorMessage());
    }
    throw new BadRequestException("检查存储桶时出错: " + e.awsErrorDetails().errorMessage());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// config-time validation: prove credentials can head the bucket
try {
    s3Client.headBucket(HeadBucketRequest.builder().bucket(bucketName).build());
} catch (S3Exception e) {
    if (e.statusCode() == 403) throw new BadRequestException("S3 凭证无效或缺少权限");
    if (e.statusCode() == 301) throw new BadRequestException("S3 region/endpoint 配置错误");
}

Try / catch

try { s3StorageService.upload(file); } catch (BadRequestException e) { if (e.getMessage().startsWith("检查存储桶时出错")) { /* 403/301 class: fix credentials or endpoint; retrying cannot help */ } }

Prevention

When it happens

Trigger: Any S3 storage operation (upload, deleteAll, download) triggering bucketExists while the configured credentials are invalid/expired, the IAM principal lacks HeadBucket rights, or the endpoint/region in amzS3Config points elsewhere (301 redirect treated as exception).

Common situations: Rotated or deleted access keys not updated in the admin S3 config; least-privilege IAM user without s3:ListBucket/HeadBucket; wrong region or a MinIO endpoint requiring path-style while configured as virtual-host; clock skew causing signature errors (403).

Related errors


AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14). Data as JSON: /api/errors/0181bb61dad2529f. Report an issue: GitHub.