floci-io/floci · error · AwsException

S3BucketDoesNotExistException

S3BucketDoesNotExistException

Error message

S3 bucket name is required.

What it means

Thrown by CreateTrail when S3BucketName is null or empty. CloudTrailService.createTrail validates the trail name first, then requires the bucket name, raising S3BucketDoesNotExistException. In real AWS the bucket must exist and permit CloudTrail writes; the emulator models only the required-name aspect with this code.

Source

Thrown at src/main/java/io/github/hectorvent/floci/services/cloudtrail/CloudTrailService.java:66

    @Inject
    public CloudTrailService(StorageFactory storageFactory, RegionResolver regionResolver,
                             IamService iamService, ObjectMapper mapper) {
        this.store = storageFactory.create("cloudtrail", "cloudtrail-trails.json",
                new TypeReference<Map<String, CloudTrailEntry>>() {});
        this.regionResolver = regionResolver;
        this.iamService = iamService;
        this.mapper = mapper;
    }

    // --- Control plane ---

    public Trail createTrail(String region, String name, String s3BucketName, String s3KeyPrefix,
                             String snsTopicArn, boolean includeGlobalServiceEvents,
                             boolean isMultiRegionTrail, boolean enableLogFileValidation,
                             boolean isOrganizationTrail) {
        validateTrailName(name);
        if (s3BucketName == null || s3BucketName.isEmpty()) {
            throw new AwsException("S3BucketDoesNotExistException", "S3 bucket name is required.", 400);
        }
        String key = regionKey(region, name);
        if (store.get(key).isPresent()) {
            throw new AwsException("TrailAlreadyExistsException",
                    "Trail " + name + " already exists.", 400);
        }
        String arn = AwsArnUtils.Arn.of("cloudtrail", region, regionResolver.getAccountId(),
                "trail/" + name).toString();
        Trail trail = new Trail(
                name, arn, s3BucketName, s3KeyPrefix, snsTopicArn,
                includeGlobalServiceEvents, isMultiRegionTrail, region,
                enableLogFileValidation, false, false, isOrganizationTrail);
        store.put(key, new CloudTrailEntry(trail, List.of(), false, null, null));
        return trail;
    }

    public void deleteTrail(String region, String trailNameOrArn) {
        Trail trail = findTrailOrThrow(region, trailNameOrArn);

View on GitHub (pinned to 62ff490619)

Solutions

  1. Pass an S3BucketName in the CreateTrail request.
  2. Create (or reference) the log-delivery bucket first and pass its exact name.
  3. Validate required CreateTrail parameters locally before sending to surface which field is missing.

Example fix

// before
client.createTrail(b -> b.name("audit").build());

// after
client.createTrail(b -> b.name("audit").s3BucketName("my-cloudtrail-logs").build());
Defensive patterns

Strategy: validation

Validate before calling

if (s3BucketName == null || s3BucketName.isEmpty()) {
    throw new IllegalArgumentException("CreateTrail requires S3BucketName");
}

Try / catch

try {
    client.createTrail(req);
} catch (S3BucketDoesNotExistException e) {
    // bucket name missing or wrong: verify config and retry with the correct name
}

Prevention

When it happens

Trigger: CreateTrail without S3BucketName — e.g. `aws cloudtrail create-trail --name t` with no --s3-bucket-name; organizations trails created from templates where the bucket variable is unset.

Common situations: Terraform/CloudFormation templates referencing an undefined bucket parameter; refactoring that renames the bucket variable but not the assignment; assuming an organization trail can omit the bucket.

Related errors


AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14). Data as JSON: /api/errors/d51989f256e36184. Report an issue: GitHub.