floci-io/floci · error · AwsException
InvalidTrailNameException
InvalidTrailNameException
Error message
Trail name is required.
What it means
First branch of validateTrailName: CreateTrail (or anything that validates a new trail name) rejects a null or empty name with InvalidTrailNameException. It is the earliest name check, so an empty name always surfaces as this error rather than the length or character rules.
Solutions
- Provide a non-empty Name (3-128 chars, letters/digits/._-, starting and ending alphanumeric).
- Assert required parameters before the call so failures name the field locally.
- Print the serialized request when debugging template-rendered calls.
Example fix
// before
client.createTrail(b -> b.s3BucketName(bucket).build());
// after
client.createTrail(b -> b.name("audit-trail").s3BucketName(bucket).build()); Defensive patterns
Strategy: validation
Validate before calling
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Trail name is required");
} Try / catch
try {
client.createTrail(req);
} catch (InvalidTrailNameException e) {
// do not retry: fix the name per the message and call again
} Prevention
- Validate all trail names with one shared helper before any CloudTrail call.
- Fail fast on empty template variables used for names.
When it happens
Trigger: CreateTrail with Name omitted, null, or an empty string — e.g. an unset template variable or a builder where name() was never called.
Common situations: Infrastructure templates with a missing name parameter; scripts deriving the trail name from an env var that is empty in CI; refactors that dropped the name assignment.
Related errors
- S3BucketDoesNotExistException
- BadRequestException
- BadRequestException
- IdempotencyException
- InvalidAction
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/1de3ae6b09c1bdbb.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/github/hectorvent/floci/services/cloudtrail/CloudTrailService.java:472
}
// Name → region-scoped only (AWS resolves a name only in the current Region)
return store.get(regionKey(region, nameOrArn))
.map(CloudTrailEntry::trail)
.orElse(null);
}
private Trail findTrailOrThrow(String region, String nameOrArn) {
Trail t = findTrail(region, nameOrArn);
if (t == null) {
throw new AwsException("TrailNotFoundException",
"Unknown trail: " + nameOrArn, 400);
}
return t;
}
private static void validateTrailName(String name) {
if (name == null || name.isEmpty()) {
throw new AwsException("InvalidTrailNameException", "Trail name is required.", 400);
}
if (name.length() < 3) {
throw new AwsException("InvalidTrailNameException",
"Trail name too short. Minimum allowed length: 3 characters.", 400);
}
if (name.length() > 128) {
throw new AwsException("InvalidTrailNameException",
"Trail name too long. Maximum allowed length: 128 characters.", 400);
}
if (!Character.isLetterOrDigit(name.charAt(0))) {
throw new AwsException("InvalidTrailNameException",
"Trail name must starts with a letter or number.", 400);
}
if (!Character.isLetterOrDigit(name.charAt(name.length() - 1))) {
throw new AwsException("InvalidTrailNameException",
"Trail name must end with a letter or number.", 400);
}
for (char c : name.toCharArray()) {View on GitHub (pinned to 62ff490619)