diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php
index 9d4a5fec05..81394f0629 100644
--- a/src/wp-includes/rest-api/class-wp-rest-server.php
+++ b/src/wp-includes/rest-api/class-wp-rest-server.php
@@ -252,6 +252,11 @@ class WP_REST_Server {
 		$send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() );
 		if ( $send_no_cache_headers ) {
 			foreach ( wp_get_nocache_headers() as $header => $header_value ) {
+				if ( empty( $header_value ) ) {
+					$this->clear_header( $header );
+					continue;
+				}
+
 				$this->send_header( $header, $header_value );
 			}
 		}
@@ -1261,6 +1266,35 @@ class WP_REST_Server {
 			$this->send_header( $key, $value );
 		}
 	}
+	/**
+	 * Sends an HTTP header.
+	 *
+	 * @since 4.4.0
+	 * @access public
+	 *
+	 * @param string $key Header key.
+	 * @param string $value Header value.
+	 */
+
+	/**
+	 * Removes an HTTP header from the current response.
+	 *
+	 * @since 4.8.0
+	 * @access public
+	 *
+	 * @param string $key Header key.
+	 */
+	public function clear_header( $key ) {
+
+		// In PHP 5.3+ there is a way to remove an already set header.
+		if ( function_exists( 'header_remove' ) ) {
+			@header_remove( $key );
+		} else {
+			// In PHP 5.2, send an empty header, but only as a
+			// last resort to override a header already sent.
+			$this->send_header( $key, '' );
+		}
+	}
 
 	/**
 	 * Retrieves the raw request entity (body).
diff --git a/tests/phpunit/includes/spy-rest-server.php b/tests/phpunit/includes/spy-rest-server.php
index 58e3c3b521..722f1b7b50 100644
--- a/tests/phpunit/includes/spy-rest-server.php
+++ b/tests/phpunit/includes/spy-rest-server.php
@@ -31,6 +31,10 @@ class Spy_REST_Server extends WP_REST_Server {
 		$this->sent_headers[ $header ] = $value;
 	}
 
+	public function clear_header( $header ) {
+		unset( $this->sent_headers[ $header ] );
+	}
+
 	/**
 	 * Override the dispatch method so we can get a handle on the request object.
 	 *
diff --git a/tests/phpunit/tests/rest-api/rest-server.php b/tests/phpunit/tests/rest-api/rest-server.php
index 046d2b5f62..1cd9e68463 100644
--- a/tests/phpunit/tests/rest-api/rest-server.php
+++ b/tests/phpunit/tests/rest-api/rest-server.php
@@ -763,9 +763,16 @@ class Tests_REST_Server extends WP_Test_REST_TestCase {
 		$headers = $this->server->sent_headers;
 
 		foreach ( wp_get_nocache_headers() as $header => $value ) {
+			if ( empty( $value ) ) {
+				continue;
+			}
+
 			$this->assertTrue( isset( $headers[ $header ] ), sprintf( 'Header %s is not present in the response.', $header ) );
 			$this->assertEquals( $value, $headers[ $header ] );
 		}
+
+		// Last-Modified should be unset as per #WP23021
+		$this->assertFalse( isset( $headers['Last-Modified'] ), 'Last-Modified should not be sent.' );
 	}
 
 	public function test_no_nocache_headers_on_unauthenticated_requests() {
