floci-io/floci · warning · AwsException
InstanceNotFound
InstanceNotFound
Error message
Instance not found: {} What it means
Thrown by DeregisterInstance (and GetInstance) when no instance with that InstanceId is registered under the given service. The emulator looks instances up by the composite key (serviceId, instanceId) and raises InstanceNotFound (HTTP 404) when absent. AWS returns the same error for deregistering an unknown or already-deregistered instance.
Source
Thrown at src/main/java/io/github/hectorvent/floci/services/cloudmap/CloudMapService.java:272
Instance instance = new Instance();
instance.setInstanceId(instanceId);
instance.setServiceId(serviceId);
instance.setCreatorRequestId(creatorRequestId != null ? creatorRequestId : UUID.randomUUID().toString());
instance.setAttributes(attributes);
boolean isNew = instanceStore.get(instanceKey(serviceId, instanceId)).isEmpty();
instanceStore.put(instanceKey(serviceId, instanceId), instance);
if (isNew) {
service.setInstanceCount(service.getInstanceCount() + 1);
}
service.setRevision(service.getRevision() + 1);
serviceStore.put(service.getId(), service);
return submitOperation("REGISTER_INSTANCE", "INSTANCE", instanceId, region);
}
public Operation deregisterInstance(String serviceId, String instanceId, String region) {
Service service = requireService(serviceId);
if (instanceStore.get(instanceKey(serviceId, instanceId)).isEmpty()) {
throw new AwsException("InstanceNotFound", "Instance not found: " + instanceId, 404);
}
instanceStore.delete(instanceKey(serviceId, instanceId));
service.setInstanceCount(Math.max(0, service.getInstanceCount() - 1));
service.setRevision(service.getRevision() + 1);
serviceStore.put(service.getId(), service);
return submitOperation("DEREGISTER_INSTANCE", "INSTANCE", instanceId, region);
}
public Instance getInstance(String serviceId, String instanceId) {
requireService(serviceId);
return instanceStore.get(instanceKey(serviceId, instanceId))
.orElseThrow(() -> new AwsException("InstanceNotFound", "Instance not found: " + instanceId, 404));
}
public List<Instance> listInstances(String serviceId) {
requireService(serviceId);
return scanInstances(serviceId);
}View on GitHub (pinned to 62ff490619)
Solutions
- Call ListInstances first and deregister only ids that are actually present.
- Treat InstanceNotFound during teardown as success (the end state — instance gone — is achieved).
- Ensure producer and consumer of the instance id agree on its source (EC2 id vs custom id).
Example fix
// before
client.deregisterInstance(b -> b.serviceId(svcId).instanceId(id)); // may throw
// after
Set<String> registered = client.listInstances(b -> b.serviceId(svcId)).instances().stream()
.map(InstanceSummary::id).collect(java.util.stream.Collectors.toSet());
if (registered.contains(id)) {
client.deregisterInstance(b -> b.serviceId(svcId).instanceId(id));
} Defensive patterns
Strategy: try-catch
Validate before calling
Set<String> registered = client.listInstances(b -> b.serviceId(svcId)).instances().stream()
.map(InstanceSummary::id).collect(Collectors.toSet());
if (!registered.contains(instanceId)) return; // nothing to do Try / catch
try {
client.deregisterInstance(b -> b.serviceId(svcId).instanceId(id));
} catch (InstanceNotFoundException e) {
// already gone: treat as success for idempotent teardown
} Prevention
- Treat deregistration as idempotent — swallow InstanceNotFound in cleanup paths.
- Resolve instance ids from ListInstances, never from stale caches.
When it happens
Trigger: DeregisterInstance with a stale instance id (instance already deregistered), an id registered under a different service, or a typo/truncation of the id; also double-teardown where two cleanup paths deregister the same instance.
Common situations: Shutdown hooks racing a deploy pipeline that already drained instances; retry logic that re-sends a deregister after a timeout even though the first attempt succeeded; using the EC2 instance id while the service stored a custom id.
Related errors
- ServiceAlreadyExists
- IdempotencyException
- NamespaceAlreadyExists
- TrailAlreadyExistsException
- TrailNotFoundException
AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14).
Data as JSON: /api/errors/5467cd1dfa449431.
Report an issue: GitHub.