floci-io/floci · error · AwsException
ResourceInUse
ResourceInUse
Error message
The namespace contains existing services and cannot be deleted.
What it means
A Cloud Map namespace cannot be deleted while any service still references it. Floci's deleteNamespace scans the service store for services whose namespaceId equals the namespace id and throws ResourceInUse (HTTP 400) when at least one is found. AWS returns the same error; deletion is a no-op until all services in the namespace are deleted first.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/cloudmap/CloudMapService.java:149
return requireNamespace(id);
}
public List<Namespace> listNamespaces(String region) {
List<Namespace> result = new ArrayList<>();
for (Namespace n : scan(namespaceStore)) {
if (region.equals(n.getRegion())) {
result.add(n);
}
}
return result;
}
public Operation deleteNamespace(String id, String region) {
Namespace ns = requireNamespace(id);
boolean hasServices = scan(serviceStore).stream()
.anyMatch(s -> ns.getId().equals(s.getNamespaceId()));
if (hasServices) {
throw new AwsException("ResourceInUse",
"The namespace contains existing services and cannot be deleted.", 400);
}
namespaceStore.delete(id);
return submitOperation("DELETE_NAMESPACE", "NAMESPACE", id, region);
}
// ──────────────────────────── Services ────────────────────────────
public Service createService(String name, String namespaceId, String creatorRequestId,
String description, String dnsConfig, String healthCheckConfig,
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.View on GitHub (pinned to 62ff490619)
Solutions
- List services with ListServices (namespace-scoped) and DeleteService each one, waiting for the delete operations to succeed, before DeleteNamespace
- Make teardown order explicit: services first, then namespace
- Catch ResourceInUse and retry after the pending service deletions complete
Example fix
// before
cloudMapClient.deleteNamespace(r -> r.id(namespaceId));
// after
cloudMapClient.listServices(r -> r.namespaceId ? null : null); // enumerate
List<ServiceSummary> services = new ArrayList<>();
String nextToken = null;
do {
final String token = nextToken;
ListServicesResponse page = cloudMapClient.listServices(r -> {
if (token != null) r.nextToken(token);
});
services.addAll(page.services());
nextToken = page.nextToken();
} while (nextToken != null);
for (ServiceSummary s : services) {
if (namespaceId.equals(s.namespaceId())) {
cloudMapClient.deleteService(r -> r.id(s.id()));
}
}
cloudMapClient.deleteNamespace(r -> r.id(namespaceId)); Defensive patterns
Strategy: validation
Validate before calling
boolean hasServices = cloudMapClient.listServices Paginator.stream(r -> r)
.flatMap(p -> p.services().stream())
.anyMatch(s -> namespaceId.equals(s.namespaceId()));
if (hasServices) {
// delete each service (and wait for the delete operation) before DeleteNamespace
} Try / catch
try {
cloudMapClient.deleteNamespace(r -> r.id(namespaceId));
} catch (ServiceDiscoveryException e) {
if ("ResourceInUse".equals(e.awsErrorDetails().errorCode())) {
// delete remaining services, wait for their operations, then retry the namespace delete
} else { throw e; }
} Prevention
- Enforce teardown order: services first, namespace last
- Wait for service delete operations to complete before deleting the namespace
When it happens
Trigger: DeleteNamespace on a namespace that contains services created via CreateService. Typical in teardown scripts that delete the namespace without enumerating and deleting its services, or when a service creation raced the delete.
Common situations: Environment teardown ordering bugs (namespace deleted before its services); test cleanup between runs; a service created asynchronously by another process just before deletion.
Related errors
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/87ad2a7ec046d846.
Report an issue: GitHub.