diff --git a/core/lib/Drupal/Component/Utility/UrlHelper.php b/core/lib/Drupal/Component/Utility/UrlHelper.php
index 20c2748..bd0712e 100644
--- a/core/lib/Drupal/Component/Utility/UrlHelper.php
+++ b/core/lib/Drupal/Component/Utility/UrlHelper.php
@@ -161,6 +161,16 @@ public static function parse($url) {
       // If there is a query string, transform it into keyed query parameters.
       if (isset($parts[1])) {
         parse_str($parts[1], $options['query']);
+
+        // Since parse_str() does not distinguish between '?key' and '?key=',
+        // feeding the url '/?key' through ::parse() and ::buildQuery()
+        // incorrectly appends a '=' to the end. Replacing empty string values
+        // with NULL should solve that problem.
+        foreach ($options['query'] as $key => &$value) {
+          if ($value === '' && strpos($parts[1], $key . '=') === FALSE) {
+            $value = NULL;
+          }
+        };
       }
     }
     // Internal URLs.
diff --git a/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php b/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php
index df35a1e05e..7d9a6b0976 100644
--- a/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php
+++ b/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php
@@ -96,6 +96,8 @@ public function providerTestAssembleWithExternalUrl() {
       ['http://example.com/test', ['https' => TRUE], 'https://example.com/test'],
       ['https://example.com/test', ['https' => FALSE], 'http://example.com/test'],
       ['https://example.com/test?foo=1#bar', [], 'https://example.com/test?foo=1#bar'],
+      ['https://example.com/test?foo', [], 'https://example.com/test?foo'],
+      ['https://example.com/test?foo=', [], 'https://example.com/test?foo='],
       'override-query' => ['https://example.com/test?foo=1#bar', ['query' => ['foo' => 2]], 'https://example.com/test?foo=2#bar'],
       'override-query-merge' => ['https://example.com/test?foo=1#bar', ['query' => ['bar' => 2]], 'https://example.com/test?foo=1&bar=2#bar'],
       'override-deep-query-merge' => ['https://example.com/test?foo=1#bar', ['query' => ['bar' => ['baz' => 'foo']]], 'https://example.com/test?foo=1&bar%5Bbaz%5D=foo#bar'],
