diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index cacd16841e17a027431680822390631ea2640353..e34677cfcb345e634209be2d94953514b8192060 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -807,11 +807,13 @@ btr_cur_optimistic_latch_leaves(
 				mode, nullptr, BUF_GET_POSSIBLY_FREED,
 				__FILE__, __LINE__, mtr, &err);
 
-			if (err == DB_DECRYPTION_FAILED) {
+			if (!cursor->left_block) {
 				cursor->index->table->file_unreadable = true;
 			}
 
-			if (btr_page_get_next(cursor->left_block->frame)
+			if (cursor->left_block->page.status
+			    == buf_page_t::FREED
+			    || btr_page_get_next(cursor->left_block->frame)
 			    != curr_page_no) {
 				/* release the left block */
 				btr_leaf_page_release(
@@ -6072,7 +6074,7 @@ btr_estimate_n_rows_in_range_on_level(
 
 		ut_ad((block != NULL) == (err == DB_SUCCESS));
 
-		if (err != DB_SUCCESS) {
+		if (!block) {
 			if (err == DB_DECRYPTION_FAILED) {
 				ib_push_warning((void *)NULL,
 					DB_DECRYPTION_FAILED,
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index be0e45f276c1852d2cab67120580acdbcd658e0a..ca66544ffa62c1bd8b7918bc45157c01926af682 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -996,6 +996,9 @@ fil_crypt_read_crypt_data(fil_space_t* space)
 						  nullptr,
 						  BUF_GET_POSSIBLY_FREED,
 						  __FILE__, __LINE__, &mtr)) {
+		if (block->page.status == buf_page_t::FREED) {
+			goto func_exit;
+		}
 		mutex_enter(&fil_system.mutex);
 		if (!space->crypt_data && !space->is_stopping()) {
 			space->crypt_data = fil_space_read_crypt_data(
@@ -1003,6 +1006,7 @@ fil_crypt_read_crypt_data(fil_space_t* space)
 		}
 		mutex_exit(&fil_system.mutex);
 	}
+func_exit:
 	mtr.commit();
 }
 
@@ -1055,6 +1059,9 @@ static bool fil_crypt_start_encrypting_space(fil_space_t* space)
 		    page_id_t(space->id, 0), space->zip_size(),
 		    RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED,
 		    __FILE__, __LINE__, &mtr, &err)) {
+		if (block->page.status == buf_page_t::FREED) {
+			goto abort;
+		}
 
 		crypt_data->type = CRYPT_SCHEME_1;
 		crypt_data->min_key_version = 0; // all pages are unencrypted
@@ -1853,7 +1860,10 @@ fil_crypt_rotate_page(
 		const lsn_t block_lsn = mach_read_from_8(FIL_PAGE_LSN + frame);
 		uint kv = buf_page_get_key_version(frame, space->flags);
 
-		if (space->is_stopping()) {
+		if (block->page.status == buf_page_t::FREED) {
+			/* Do not modify freed pages to avoid an assertion
+			failure on recovery.*/
+		} else if (space->is_stopping()) {
 			/* The tablespace is closing (in DROP TABLE or
 			TRUNCATE TABLE or similar): avoid further access */
 		} else if (!kv && !*reinterpret_cast<uint16_t*>
@@ -1882,9 +1892,6 @@ fil_crypt_rotate_page(
 			some dummy pages will be allocated, with 0 in
 			the FIL_PAGE_TYPE. Those pages should be
 			skipped from key rotation forever. */
-		} else if (block->page.status == buf_page_t::FREED) {
-			/* Do not modify freed pages to avoid an assertion
-			failure on recovery.*/
 		} else if (fil_crypt_needs_rotation(
 				crypt_data,
 				kv,
@@ -2035,8 +2042,10 @@ fil_crypt_flush_space(
 		    page_id_t(space->id, 0), space->zip_size(),
 		    RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED,
 		    __FILE__, __LINE__, &mtr)) {
-		mtr.set_named_space(space);
-		crypt_data->write_page0(block, &mtr);
+		if (block->page.status != buf_page_t::FREED) {
+			mtr.set_named_space(space);
+			crypt_data->write_page0(block, &mtr);
+		}
 	}
 
 	mtr.commit();
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 34464e38b2152c6f1379cb2be6131960f916d798..ceaab79b1c418cbd690acf34881e915b9b4a0024 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -417,6 +417,10 @@ xdes_get_descriptor_const(
 						  __FILE__, __LINE__, mtr)) {
 		buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
 
+		if (block->page.status == buf_page_t::FREED) {
+			return nullptr;
+		}
+
 		ut_ad(page != 0 || space->free_limit == mach_read_from_4(
 			      FSP_FREE_LIMIT + FSP_HEADER_OFFSET
 			      + block->frame));
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index cec1eb22d2866db6f39f33f5638f91a717957bad..56f6d971271a5749810ccb75f7bcc91491abfa3e 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -4995,7 +4995,7 @@ static void lock_rec_block_validate(const page_id_t page_id)
 				   << page_id << " err " << err;
 		}
 
-		if (block) {
+		if (block && block->page.status != buf_page_t::FREED) {
 			buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
 
 			ut_ad(lock_rec_validate_page(block));
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 67f8a2b5277d8dd612cce21f15f3d1b4447936ea..7c9d8af0859c00d5dd32e2c12fc5b335c421d2fb 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2421,6 +2421,7 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
 		any buffered changes. */
 		init->created = false;
 		ut_ad(!mtr.has_modifications());
+		block->page.status = buf_page_t::FREED;
 	}
 
 	/* Make sure that committing mtr does not change the modification