diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php
index b71a83761c..2417bcdf76 100644
--- a/src/wp-includes/functions.php
+++ b/src/wp-includes/functions.php
@@ -1169,6 +1169,7 @@ function add_query_arg( ...$args ) {
 	$ret = preg_replace( '#=(&|$)#', '$1', $ret );
 	$ret = $protocol . $base . $ret . $frag;
 	$ret = rtrim( $ret, '?' );
+	$ret = str_replace( '?#', '#', $ret );
 	return $ret;
 }
 
diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php
index bcf8525216..4750bfcb9c 100644
--- a/tests/phpunit/tests/functions.php
+++ b/tests/phpunit/tests/functions.php
@@ -665,6 +665,23 @@ class Tests_Functions extends WP_UnitTestCase {
 		$this->assertSame( 'foo=bar&1=2', $url );
 	}
 
+	/**
+	 * Tests that add_query_arg removes the question mark when
+	 * a parameter is set to false.
+	 *
+	 * @ticket 44499
+	 *
+	 * @group add_query_arg
+	 *
+	 * @covers ::add_query_arg
+	 */
+	public function test_add_query_arg_removes_question_mark() {
+		$url      = 'http://example.org?param=value#anchor';
+		$expected = 'http://example.org#anchor';
+		$actual   = add_query_arg( 'param', false, $url );
+		$this->assertSame( $expected, $actual );
+	}
+
 	/**
 	 * @ticket 21594
 	 */
