elunez/eladmin · error · BadRequestException
创建存储桶时出错: {}
Error message
创建存储桶时出错: {} What it means
BadRequestException thrown from createBucket(bucketName) when the bucket-creation flow (CreateBucket + S3Waiter.waitUntilBucketExists) fails with an S3Exception other than BucketAlreadyOwnedByYou. Typical appended details: AccessDenied (no s3:CreateBucket), BucketAlreadyExists (name owned by another account globally), InvalidBucketName, or IllegalLocationConstraint for a wrong-region create.
Source
Thrown at eladmin-tools/src/main/java/me/zhengjie/service/impl/S3StorageServiceImpl.java:260
S3Waiter s3Waiter = s3Client.waiter();
CreateBucketRequest bucketRequest = CreateBucketRequest.builder()
.bucket(bucketName)
.acl(BucketCannedACL.PRIVATE)
.build();
s3Client.createBucket(bucketRequest);
// 等待直到存储桶创建完成
HeadBucketRequest bucketRequestWait = HeadBucketRequest.builder()
.bucket(bucketName)
.build();
// 使用 WaiterResponse 等待存储桶存在
WaiterResponse<HeadBucketResponse> waiterResponse = s3Waiter.waitUntilBucketExists(bucketRequestWait);
waiterResponse.matched().response().ifPresent(response ->
log.info("存储桶 '{}' 创建成功,状态: {}", bucketName, response.sdkHttpResponse().statusCode())
);
} catch (BucketAlreadyOwnedByYouException e) {
log.warn("存储桶 '{}' 已经被您拥有,无需重复创建。", bucketName);
} catch (S3Exception e) {
throw new BadRequestException("创建存储桶时出错: " + e.awsErrorDetails().errorMessage());
}
return true;
}
}View on GitHub (pinned to 55fbf70595)
Solutions
- Pre-create the bucket manually in the console/MinIO so upload never needs auto-create.
- Read the appended AWS message: AccessDenied -> grant s3:CreateBucket; BucketAlreadyExists -> pick a unique name and update config.
- Ensure the S3Client's region matches where the bucket may be created (region constraint mismatch raises IllegalLocationConstraint).
- For MinIO, follow its bucket-create semantics (region 'us-east-1' default).
- Re-run the upload after fixing; createBucket returning true proceeds normally.
Example fix
// before
} catch (S3Exception e) {
throw new BadRequestException("创建存储桶时出错: " + e.awsErrorDetails().errorMessage());
}
return true;
// after: treat 'already exists elsewhere' distinctly
catch (S3Exception e) {
if (e.statusCode() == 409) {
throw new BadRequestException("存储桶名已被其他账户占用,请更换桶名");
}
throw new BadRequestException("创建存储桶时出错: " + e.awsErrorDetails().errorMessage());
}
return true; Defensive patterns
Strategy: fallback
Validate before calling
// prefer explicit pre-creation; only auto-create with a proven-valid name
String bucket = amzS3Config.getDefaultBucket();
if (!bucket.matches("^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$")) {
throw new BadRequestException("存储桶名称不符合 S3 规范: " + bucket);
} Try / catch
try { s3StorageService.upload(file); } catch (BadRequestException e) { if (e.getMessage().startsWith("创建存储桶时出错")) { /* fallback: admin creates bucket manually, then retry the upload once */ } } Prevention
- Create buckets as a provisioning step; treat upload-time creation as a convenience, not the plan.
- Choose globally unique bucket names — S3's namespace is shared across all accounts.
- Match client region to the intended bucket location constraint.
When it happens
Trigger: First upload to a configured-but-missing bucket (see error 91's call site) while: the IAM principal lacks CreateBucket; the name is globally taken (S3 namespace is worldwide); the client's region doesn't match the bucket-location constraint; or a compatible store rejects the create.
Common situations: Least-privilege keys; choosing a generic bucket name like 'my-files' that someone else owns; MinIO endpoints that require a specific LocationConstraint; waiter timing out and surfacing a failure response as S3Exception.
Related errors
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/59a555f99559e3e8.
Report an issue: GitHub.