diff --git a/src/plugins/fake/log.c b/src/plugins/fake/log.c
index fd9cea885f7192db684050df7fd5e15ed50e62fb..d4fedd13528112ce05f0a04a9fd342f78576ada2 100644
--- a/src/plugins/fake/log.c
+++ b/src/plugins/fake/log.c
@@ -27,8 +27,8 @@
 #include "../../core/util.h"
 
 #include <string.h>
-#include <assert.h>
 #include <arpa/inet.h>
+#include <inttypes.h>
 
 /*
  * Single event in the log.
@@ -117,7 +117,7 @@ static void log_clean_internal(struct log *log, struct mem_pool *tmp_pool, uint6
 		.now = now
 	};
 	if (log->limit_trie) {
-		assert(tmp_pool);
+		sanity(tmp_pool, "Missing temporary pool\n");
 		trie_walk(log->limit_trie, holdback_store, &tmp, tmp_pool);
 	}
 	mem_pool_reset(log->pool);
@@ -252,9 +252,9 @@ uint8_t *log_dump(struct context *context, struct log *log, size_t *size) {
 	size_t rest = *size - 1;
 	*result = 'L';
 	LFOR(log, event, log) {
-		assert(event->timestamp + limit > now);
-		assert(event->addr_len == 4 || event->addr_len == 16);
-		assert(event->info_count < 16);
+		sanity(event->timestamp + limit > now, "Timestamp %" PRIu64 " is too old for current time %" PRIu64 "\n", event->timestamp, now);
+		sanity(event->addr_len == 4 || event->addr_len == 16, "Wrong event address length %hhu\n", event->addr_len);
+		sanity(event->info_count < 16, "Too many additional info records: %hhu\n", event->info_count);
 		struct event_header header = {
 			.timestamp = htonl(now - event->timestamp),
 			.type = event->type,
@@ -263,7 +263,7 @@ uint8_t *log_dump(struct context *context, struct log *log, size_t *size) {
 			.code = event->code,
 			.remote_port = htons(event->rem_port)
 		};
-		assert(rest >= 2 * event->addr_len + sizeof header);
+		sanity(rest >= 2 * event->addr_len + sizeof header, "Not enough buffer space, %zu available, %zu needed\n", rest, 2 * event->addr_len + sizeof header);
 		memcpy(pos, &header, sizeof header);
 		pos += sizeof header;
 		memcpy(pos, event->rem_addr, event->addr_len);
@@ -271,15 +271,15 @@ uint8_t *log_dump(struct context *context, struct log *log, size_t *size) {
 		pos += 2 * event->addr_len;
 		rest -= 2 * event->addr_len + sizeof header;
 		for (size_t i = 0; i < event->info_count; i ++) {
-			assert(rest > 0);
-			assert(event->extra_info[i].type != EI_LAST);
+			sanity(rest > 0, "No buffer space available for additional info\n");
+			sanity(event->extra_info[i].type != EI_LAST, "Last additional info in the middle of array\n");
 			*pos ++ = event->extra_info[i].type;
 			rest --;
 			uplink_render_string(event->extra_info[i].content, strlen(event->extra_info[i].content), &pos, &rest);
 		}
 	}
-	assert(pos == result + *size);
-	assert(rest == 0);
+	sanity(pos == result + *size, "Length and pointer mismatch at log dump\n");
+	sanity(rest == 0, "Log dump buffer leftover of %zu bytes\n", rest);
 	return result;
 }
 
diff --git a/src/plugins/fake/main.c b/src/plugins/fake/main.c
index ca7154e6a508b592ff211b86a934cc95a7a9492c..aafbf76bc61b9fd4d2cddacedbe45ecbdd97e47b 100644
--- a/src/plugins/fake/main.c
+++ b/src/plugins/fake/main.c
@@ -30,7 +30,6 @@
 
 #include <string.h>
 #include <errno.h>
-#include <assert.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -262,7 +261,7 @@ static void push_info(struct event_info *infos, size_t *pos, const char *content
 			.type = type,
 			.content = content
 		};
-		assert(*pos < MAX_INFOS);
+		sanity(*pos < MAX_INFOS, "Pushing too many additional infos\n");
 		infos[*pos].type = EI_LAST;
 	}
 }
@@ -287,8 +286,8 @@ static void send_timeout(struct context *context, void *data __attribute__((unus
 static void log_wrapper(struct context *context, struct fd_tag *tag, enum event_type type, const char *reason, const char *username, const char *password) {
 	ulog(LLOG_DEBUG, "Logging event %hhu for tag %p\n", (uint8_t)type, (void *)tag);
 	struct user_data *u = context->user_data;
-	assert(tag->rem_addr.sin6_family == AF_INET6);
-	assert(tag->loc_addr.sin6_family == AF_INET6);
+	sanity(tag->rem_addr.sin6_family == AF_INET6, "Wrong remote address family %hhu\n", (uint8_t)tag->rem_addr.sin6_family);
+	sanity(tag->loc_addr.sin6_family == AF_INET6, "Wrong local address family %hhu\n", (uint8_t)tag->loc_addr.sin6_family);
 	struct event_info infos[MAX_INFOS] = { [0] = { .type = EI_LAST } };
 	size_t evpos = 0;
 	push_info(infos, &evpos, reason, EI_REASON);
@@ -325,7 +324,7 @@ void conn_log_attempt(struct context *context, struct fd_tag *tag, const char *u
 
 static void conn_inactive(struct context *context, void *data, size_t id) {
 	struct fd_tag *tag = data;
-	assert(tag->inactivity_timeout == id);
+	sanity(tag->inactivity_timeout == id, "Inactivity timeout ID mismatch\n");
 	ulog(LLOG_DEBUG, "Connection %p/%p with FD %d of fake server %s timed out after %u ms\n", (void *)tag->conn, (void *)tag, tag->fd, tag->desc->name, tag->desc->conn_timeout);
 	tag->inactivity_timeout_active = false; // It fired, no longer active.
 	log_wrapper(context, tag, EVENT_TIMEOUT, NULL, NULL, NULL);
@@ -356,8 +355,8 @@ static void fd_ready(struct context *context, int fd, void *tag) {
 				break;
 			}
 		if (empty) {
-			assert(empty->desc == t->desc);
-			assert(empty->server == t->server);
+			sanity(empty->desc == t->desc, "Description mismatch\n");
+			sanity(empty->server == t->server, "Server mismatch\n");
 			empty->addr_len = sizeof empty->rem_addr;
 			struct sockaddr *addr_p = (struct sockaddr *)&empty->rem_addr;
 			int new = accept(fd, addr_p, &empty->addr_len);
@@ -368,8 +367,8 @@ static void fd_ready(struct context *context, int fd, void *tag) {
 			loop_plugin_register_fd(context, new, empty);
 			ulog(LLOG_DEBUG, "Accepted connecion %d from %s on FD %d for fake server %s\n", new, addr2str(context->temp_pool, addr_p, empty->addr_len), fd, t->desc->name);
 			socklen_t len = sizeof empty->loc_addr;
-			assert(getsockname(new, (struct sockaddr *)&empty->loc_addr, &len) == 0);
-			assert(len == empty->addr_len);
+			sanity(getsockname(new, (struct sockaddr *)&empty->loc_addr, &len) == 0, "getsockname failed: %s\n", strerror(errno));
+			sanity(len == empty->addr_len, "getsockname returned wrong address length %zu\n", (size_t)len);
 			empty->fd = new;
 			empty->closed = false;
 			if (empty->desc->conn_set_fd_cb)
@@ -389,8 +388,8 @@ static void fd_ready(struct context *context, int fd, void *tag) {
 			}
 			ulog(LLOG_WARN, "Throwing out connection %d from %s accepted on %d of fake server %s, too many opened ones\n", fd, addr2str(context->temp_pool, addr_p, aux_tag.addr_len), fd, t->desc->name);
 			socklen_t len = sizeof aux_tag.loc_addr;
-			assert(getsockname(new, (struct sockaddr *)&aux_tag.loc_addr, &len));
-			assert(len == aux_tag.addr_len);
+			sanity(getsockname(new, (struct sockaddr *)&aux_tag.loc_addr, &len) == 0, "getsockname failed: %s\n", strerror(errno));
+			sanity(len == aux_tag.addr_len, "getsockname returned wrong address length %zu\n", (size_t)len);
 			if (close(new) == -1) {
 				ulog(LLOG_ERROR, "Error throwing newly accepted connection %d from %s accepted on %d of fake server %s: %s\n", new, addr2str(context->temp_pool, addr_p, aux_tag.addr_len), fd, t->desc->name, strerror(errno));
 			}
diff --git a/src/plugins/fake/telnet.c b/src/plugins/fake/telnet.c
index a14b2558fc88f3557edd5a46455237ec0b4204c0..83480e73d0171bcef75298c016b57b062274c5d4 100644
--- a/src/plugins/fake/telnet.c
+++ b/src/plugins/fake/telnet.c
@@ -28,7 +28,6 @@
 #include <string.h>
 #include <stdbool.h>
 #include <errno.h>
-#include <assert.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 
@@ -184,7 +183,7 @@ static bool process_line(struct context *context, struct fd_tag *tag, struct con
 	(void)tag;
 	switch (conn->position) {
 		case WANT_LOGIN:
-			assert(conn->line);
+			sanity(conn->line, "Missing line buffer for login name\n");
 			*conn->line = '\0';
 			conn->line = conn->line_base = conn->password;
 			if (!ask_for(context, conn, "password"))
@@ -194,7 +193,7 @@ static bool process_line(struct context *context, struct fd_tag *tag, struct con
 		case WANT_PASSWORD:
 			conn->position = WAIT_DENIAL;
 			conn->denial_timeout = loop_timeout_add(context->loop, denial_timeout, context, conn, send_denial);
-			assert(conn->line);
+			sanity(conn->line, "Missing line buffer for password\n");
 			*conn->line = '\0';
 			conn_log_attempt(context, tag, conn->username, conn->password);
 			conn->line = conn->line_base = NULL;
@@ -276,7 +275,7 @@ static bool char_handle(struct context *context, struct fd_tag *tag, struct conn
 			conn->expect = EXPECT_NONE;
 			return true;
 		default:
-			assert(0); // Invalid expect state
+			insane("Invalid expected state %u\n", (unsigned)conn->expect);
 	}
 	// We are in a normal mode, decide if we see anything special
 	switch (ch) {