floci-io/floci · error · AwsException
ServiceAlreadyExists
ServiceAlreadyExists
Error message
A service named \"{}\" already exists. What it means
Thrown when CreateService would create a second service with the same name in the same namespace and region. CloudMapService scans the service store for (region, name, namespaceId) equality — namespace id may come from the top-level field or be extracted from DnsConfig — and raises ServiceAlreadyExists before constructing the new service. AWS enforces the same uniqueness: service names are unique within a namespace.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/cloudmap/CloudMapService.java:178
String healthCheckCustomConfig, String type,
Map<String, String> tags, String region) {
if (name == null || name.isBlank()) {
throw new AwsException("InvalidInput", "Service name is required.", 400);
}
String resolvedNamespaceId = namespaceId;
if (dnsConfig != null && resolvedNamespaceId == null) {
// DnsConfig may carry the namespace id when the top-level field is absent.
resolvedNamespaceId = dnsConfigNamespaceId(dnsConfig);
}
if (resolvedNamespaceId != null) {
requireNamespace(resolvedNamespaceId);
}
final String nsId = resolvedNamespaceId;
boolean exists = scan(serviceStore).stream()
.anyMatch(s -> region.equals(s.getRegion()) && name.equals(s.getName())
&& java.util.Objects.equals(nsId, s.getNamespaceId()));
if (exists) {
throw new AwsException("ServiceAlreadyExists",
"A service named \"" + name + "\" already exists.", 400);
}
Service service = new Service();
service.setId("srv-" + randomId(20));
service.setName(name);
service.setNamespaceId(nsId);
service.setDescription(description);
service.setDnsConfig(dnsConfig);
service.setHealthCheckConfig(healthCheckConfig);
service.setHealthCheckCustomConfig(healthCheckCustomConfig);
service.setType(resolveServiceType(type, dnsConfig));
service.setCreatorRequestId(creatorRequestId != null ? creatorRequestId : UUID.randomUUID().toString());
service.setCreateDate(Instant.now());
service.setRegion(region);
service.setInstanceCount(0);
service.setRevision(0L);
if (tags != null) {
service.setTags(tags);View on GitHub (pinned to 62ff490619)
Solutions
- Before creating, call ListServices filtered by namespace and check whether the name already exists; reuse it instead of creating.
- Delete the stale service (DeregisterInstance first, then DeleteService) if it is leftover from a previous run.
- Suffix generated names (e.g. orders-service-<env>-<build>) when concurrent runs may collide.
- If the collision is unexpected, verify which namespace id the request resolves to — DnsConfig can carry one when the top-level NamespaceId is absent.
Example fix
// before
client.createService(b -> b.name("orders").namespaceId(nsId));
// after
boolean exists = client.listServices(b -> b.namespaceId(nsId)).services().stream()
.anyMatch(s -> s.name().equals("orders"));
if (!exists) {
client.createService(b -> b.name("orders").namespaceId(nsId));
} Defensive patterns
Strategy: validation
Validate before calling
boolean exists = client.listServices(b -> b.namespaceId(nsId)).services().stream()
.anyMatch(s -> s.name().equals(name));
if (exists) { /* reuse existing service instead of creating */ } Try / catch
try {
client.createService(req);
} catch (ServiceAlreadyExistsException e) {
// adopt the existing service: fetch it and continue
} Prevention
- Make provisioning scripts idempotent: list-before-create with a stable naming scheme.
- Keep namespace ids stable across runs so uniqueness checks compare like with like.
When it happens
Trigger: Running CreateService twice with the same Name and NamespaceId in the same region; re-running an idempotent-looking deployment script without cleanup; passing a different namespace id casing/format (e.g. id pulled from DnsConfig instead of the top-level field) and expecting it to be a distinct service — the emulator treats a matching resolved namespace id as a collision.
Common situations: CI pipelines that provision Cloud Map services on every run against a persistent Floci storage mode; drift between what a previous run created and what the script assumes; renaming logic that creates-then-deletes and fails halfway.
Related errors
- InstanceNotFound
- TrailAlreadyExistsException
- ResourceInUseException
- ConflictException
- NamespaceAlreadyExists
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/72aa7e264376ae61.
Report an issue: GitHub.