diff --git a/emper/io/Future.cpp b/emper/io/Future.cpp
index 50870da12840b081c539b263cf88ca3dd9d95bfc..71a6dab8e053b1745028ffecc0afd53fa7b05959 100644
--- a/emper/io/Future.cpp
+++ b/emper/io/Future.cpp
@@ -88,7 +88,7 @@ auto Future::cancel() -> int32_t {
 	state.cancelled = true;
 
 	if (!isSubmitted() || isForgotten()) {
-		LOGW("Cancelling unsubmitted or forgotten " << this);
+		LOGW("Cancelling " << (isForgotten() ? "forgotten " : "unsubmitted ") << this);
 		return -ENOENT;
 	}
 
diff --git a/emper/io/Future.hpp b/emper/io/Future.hpp
index d0978de740cc9c636b812765ef2cb6d3fa76d723..c559ba996e9e7b57ac5f6dd30f3cbd34b2a91822 100644
--- a/emper/io/Future.hpp
+++ b/emper/io/Future.hpp
@@ -137,12 +137,12 @@ class Future : public Logger<LogSubsystem::IO> {
 	// only if callback is set and if callback is set ~Future does not call cancel.
 	// NOLINTNEXTLINE(bugprone-exception-escape)
 	virtual ~Future() {
-		if (isForgotten() || callback) {
+		if (isForgotten() || isRetrieved() || isCancelled() || callback) {
 			return;
 		}
 
 		if constexpr (emper::DEBUG) {
-			if (!isRetrieved() && !isDependency() && !isCancelled()) {
+			if (!isDependency()) {
 				LOGE(this << " created but never awaited");
 				abort();
 			}
diff --git a/tests/io/CancelFutureTest.cpp b/tests/io/CancelFutureTest.cpp
index 0ff9b09f38367b7a8b37a2ebd9662472847fb371..829a8a9f3ff2e3fa27f98d33c0a1b6797973100f 100644
--- a/tests/io/CancelFutureTest.cpp
+++ b/tests/io/CancelFutureTest.cpp
@@ -12,44 +12,55 @@
 using emper::io::ReadFuture;
 using emper::io::WriteFuture;
 
-void emperTest() {
-	int efd = eventfd(0, 0);
-	if (efd == -1) {
-		DIE_MSG_ERRNO("eventfd failed");
-	}
+int efd;
+uint64_t read_buf;
+uint64_t write_buf = 42;
 
-	uint64_t read_buf;
-	uint64_t write_buf = 42;
-	// cancel not submitted Future
+void cancelNotSubmitted() {
 	ReadFuture readFuture(efd, &read_buf, sizeof(read_buf), 0);
 	assert(readFuture.cancel() == -ENOENT);
+}
 
-	// cancel submitted non-completed Future
+void cancelSubmittedNotCompleted() {
+	ReadFuture readFuture(efd, &read_buf, sizeof(read_buf), 0);
 	readFuture.submit();
 	assert(readFuture.cancel() == -ECANCELED);
+}
 
-	readFuture.reset();
-
+void cancelCompleted() {
+	ReadFuture readFuture(efd, &read_buf, sizeof(read_buf), 0);
 	readFuture.submit();
 	WriteFuture writeFuture(efd, &write_buf, sizeof(write_buf), 0);
 	assert(writeFuture.submitAndWait() == sizeof(write_buf));
 	assert(readFuture.cancel() == sizeof(write_buf) && read_buf == write_buf);
+}
+
+void cancelNotCompletedChain() {
+	ReadFuture readFuture(efd, &read_buf, sizeof(read_buf), 0);
+	ReadFuture readFuture2(efd, &read_buf, sizeof(read_buf), 0);
+	readFuture2.setDependency(readFuture);
 
-	writeFuture.reset();
-	read_buf = 0;
-	readFuture.reset();
+	readFuture2.submit();
+	assert(readFuture2.cancel() == -ECANCELED);
+	assert(readFuture.wait() == -ECANCELED);
+}
 
-	// cancel a chain
+void cancelPartialCompletedChain() {
+	ReadFuture readFuture(efd, &read_buf, sizeof(read_buf), 0);
 	ReadFuture readFuture2(efd, &read_buf, sizeof(read_buf), 0);
 	readFuture2.setDependency(readFuture);
+
 	readFuture2.submit();
 	assert(readFuture2.cancel() == -ECANCELED);
 	assert(readFuture.wait() == -ECANCELED);
+}
 
-	readFuture2.reset();
-	readFuture.reset();
+void cancelNotCompletedFutureChain() {
+	ReadFuture readFuture(efd, &read_buf, sizeof(read_buf), 0);
+	WriteFuture writeFuture(efd, &write_buf, sizeof(write_buf), 0);
+	ReadFuture readFuture2(efd, &read_buf, sizeof(read_buf), 0);
+	readFuture2.setDependency(readFuture);
 
-	// cancel partial completed chain
 	readFuture2.submit();
 	assert(writeFuture.submitAndWait() == sizeof(write_buf));
 	// TODO: investigate why this read is completed with -EINTR most of the time
@@ -57,3 +68,16 @@ void emperTest() {
 	assert(r == -EINTR || r == -ECANCELED);
 	assert(readFuture.wait() == sizeof(write_buf) && read_buf == write_buf);
 }
+
+void emperTest() {
+	efd = eventfd(0, 0);
+	if (efd == -1) {
+		DIE_MSG_ERRNO("eventfd failed");
+	}
+
+	cancelNotSubmitted();
+	cancelSubmittedNotCompleted();
+	cancelCompleted();
+	cancelNotCompletedChain();
+	cancelPartialCompletedChain();
+}