diff --git a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
index a552a0e..9f65cae 100644
--- a/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
+++ b/core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
@@ -27,7 +27,7 @@
  *   description = @Translation("Stores a URL string, optional varchar link text, and optional blob of attributes to assemble a link."),
  *   default_widget = "link_default",
  *   default_formatter = "link",
- *   constraints = {"LinkType" = {}, "LinkAccess" = {}, "LinkExternalProtocols" = {}, "LinkNotExistingInternal" = {}}
+ *   constraints = {"LinkType" = {}, "LinkAccess" = {}}
  * )
  */
 class LinkItem extends FieldItemBase implements LinkItemInterface {
diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
index 33152aa..0e8ebc2 100644
--- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -57,7 +57,7 @@ public static function defaultSettings() {
    *
    * @see static::getUserEnteredStringAsUri()
    */
-  public static function getUriAsDisplayableString($uri) {
+  protected static function getUriAsDisplayableString($uri) {
     $scheme = parse_url($uri, PHP_URL_SCHEME);
 
     // By default, the displayable string is the URI.
@@ -147,6 +147,31 @@ public static function validateUriElement($element, FormStateInterface $form_sta
       $form_state->setError($element, t('Manually entered paths should start with /, ? or #.'));
       return;
     }
+
+    // If the URI is empty or not well-formed, the link field type's validation
+    // constraint will detect it.
+    // @see \Drupal\link\Plugin\Validation\Constraint\LinkTypeConstraint::validate()
+    if (!empty($uri) && parse_url($uri)) {
+      $url = Url::fromUri($uri);
+
+      // Disallow unrouted internal URLs (i.e. disallow 'base:' URIs).
+      $disallowed  = !$url->isRouted() && !$url->isExternal();
+      // Disallow external URLs using untrusted protocols.
+      $disallowed = $disallowed || ($url->isExternal() && !in_array(parse_url($uri, PHP_URL_SCHEME), UrlHelper::getAllowedProtocols()));
+      // Disallow routed URLs that don't exist.
+      if (!$disallowed && $url->isRouted()) {
+        try {
+          $url->toString();
+        }
+        catch (RouteNotFoundException $e) {
+          $disallowed = TRUE;
+        }
+      }
+
+      if ($disallowed) {
+        $form_state->setError($element, t("The path '@link_path' is invalid.", ['@link_path' => static::getUriAsDisplayableString($uri)]));
+      }
+    }
   }
 
   /**
diff --git a/core/modules/link/src/Plugin/Validation/Constraint/LinkAccessConstraintValidator.php b/core/modules/link/src/Plugin/Validation/Constraint/LinkAccessConstraintValidator.php
index 7bee72d..7011ff3 100644
--- a/core/modules/link/src/Plugin/Validation/Constraint/LinkAccessConstraintValidator.php
+++ b/core/modules/link/src/Plugin/Validation/Constraint/LinkAccessConstraintValidator.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Session\AccountProxyInterface;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
-use Drupal\link\Plugin\Field\FieldWidget\LinkWidget;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\ConstraintValidatorInterface;
@@ -76,7 +75,7 @@ public function validate($value, Constraint $constraint) {
       // permission nor can access this URI.
       $allowed = $this->current_user->hasPermission('link to any page') || $url->access();
       if (!$allowed) {
-        $this->context->addViolation($constraint->message, array('@uri' => LinkWidget::getUriAsDisplayableString($value->uri)));
+        $this->context->addViolation($constraint->message, array('@uri' => $value->uri));
       }
     }
   }
diff --git a/core/modules/link/src/Plugin/Validation/Constraint/LinkExternalProtocolsConstraint.php b/core/modules/link/src/Plugin/Validation/Constraint/LinkExternalProtocolsConstraint.php
deleted file mode 100644
index 4b6b7e0..0000000
--- a/core/modules/link/src/Plugin/Validation/Constraint/LinkExternalProtocolsConstraint.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\link\Plugin\Validation\Constraint\LinkExternalProtocols.
- */
-
-namespace Drupal\link\Plugin\Validation\Constraint;
-
-use Symfony\Component\Validator\Constraint;
-
-/**
- * Defines an protocol validation constraint for links to external URLs.
- *
- * @Plugin(
- *   id = "LinkExternalProtocols",
- *   label = @Translation("No harmful external protocols", context = "Validation"),
- * )
- */
-class LinkExternalProtocolsConstraint extends Constraint {
-
-  public $message = "The path '@uri' is invalid.";
-
-}
diff --git a/core/modules/link/src/Plugin/Validation/Constraint/LinkExternalProtocolsConstraintValidator.php b/core/modules/link/src/Plugin/Validation/Constraint/LinkExternalProtocolsConstraintValidator.php
deleted file mode 100644
index 42a0618..0000000
--- a/core/modules/link/src/Plugin/Validation/Constraint/LinkExternalProtocolsConstraintValidator.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\link\Plugin\Validation\Constraint\LinkExternalProtocolsValidator.
- */
-
-namespace Drupal\link\Plugin\Validation\Constraint;
-
-use Drupal\Component\Utility\UrlHelper;
-use Drupal\link\Plugin\Field\FieldWidget\LinkWidget;
-use Symfony\Component\Validator\Constraint;
-use Symfony\Component\Validator\ConstraintValidatorInterface;
-use Symfony\Component\Validator\ExecutionContextInterface;
-
-/**
- * Validates the LinkExternalProtocols constraint.
- */
-class LinkExternalProtocolsConstraintValidator implements ConstraintValidatorInterface {
-
-  /**
-   * Stores the validator's state during validation.
-   *
-   * @var \Symfony\Component\Validator\ExecutionContextInterface
-   */
-  protected $context;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function initialize(ExecutionContextInterface $context) {
-    $this->context = $context;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validate($value, Constraint $constraint) {
-    if (isset($value)) {
-      try {
-        /** @var \Drupal\Core\Url $url */
-        $url = $value->getUrl();
-      } // If the URL is malformed this constraint cannot check further.
-      catch (\InvalidArgumentException $e) {
-        return;
-      }
-      // Disallow external URLs using untrusted protocols.
-      if ($url->isExternal() && !in_array(parse_url($url->getUri(), PHP_URL_SCHEME), UrlHelper::getAllowedProtocols())) {
-        $this->context->addViolation($constraint->message, array('@uri' => LinkWidget::getUriAsDisplayableString($value->uri)));
-      }
-    }
-  }
-
-}
diff --git a/core/modules/link/src/Plugin/Validation/Constraint/LinkNotExistingInternalConstraint.php b/core/modules/link/src/Plugin/Validation/Constraint/LinkNotExistingInternalConstraint.php
deleted file mode 100644
index d21e75b..0000000
--- a/core/modules/link/src/Plugin/Validation/Constraint/LinkNotExistingInternalConstraint.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\link\Plugin\Validation\Constraint\LinkNotExistingInternal.
- */
-
-namespace Drupal\link\Plugin\Validation\Constraint;
-
-use Symfony\Component\Validator\Constraint;
-
-/**
- * Defines an protocol validation constraint for links to broken internal URLs.
- *
- * @Plugin(
- *   id = "LinkNotExistingInternal",
- *   label = @Translation("No broken internal links", context = "Validation"),
- * )
- */
-class LinkNotExistingInternalConstraint extends Constraint {
-
-  public $message = "The path '@uri' is invalid.";
-
-}
diff --git a/core/modules/link/src/Plugin/Validation/Constraint/LinkNotExistingInternalConstraintValidator.php b/core/modules/link/src/Plugin/Validation/Constraint/LinkNotExistingInternalConstraintValidator.php
deleted file mode 100644
index 93b56cc..0000000
--- a/core/modules/link/src/Plugin/Validation/Constraint/LinkNotExistingInternalConstraintValidator.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\link\Plugin\Validation\Constraint\LinkNotExistingInternalConstraintValidator.
- */
-
-namespace Drupal\link\Plugin\Validation\Constraint;
-
-use Drupal\link\Plugin\Field\FieldWidget\LinkWidget;
-use Symfony\Component\Routing\Exception\RouteNotFoundException;
-use Symfony\Component\Validator\Constraint;
-use Symfony\Component\Validator\ConstraintValidatorInterface;
-use Symfony\Component\Validator\ExecutionContextInterface;
-
-/**
- * Validates the LinkNotExistingInternal constraint.
- */
-class LinkNotExistingInternalConstraintValidator implements ConstraintValidatorInterface {
-
-  /**
-   * Stores the validator's state during validation.
-   *
-   * @var \Symfony\Component\Validator\ExecutionContextInterface
-   */
-  protected $context;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function initialize(ExecutionContextInterface $context) {
-    $this->context = $context;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validate($value, Constraint $constraint) {
-    if (isset($value)) {
-      try {
-        /** @var \Drupal\Core\Url $url */
-        $url = $value->getUrl();
-      } // If the URL is malformed this constraint cannot check further.
-      catch (\InvalidArgumentException $e) {
-        return;
-      }
-
-      if ($url->isRouted()) {
-        $allowed = FALSE;
-        try {
-          $url->toString();
-        }
-        catch (RouteNotFoundException $e) {
-          $allowed = TRUE;
-        }
-        if (!$allowed) {
-          $this->context->addViolation($constraint->message, array('@uri' => LinkWidget::getUriAsDisplayableString($value->uri)));
-        }
-      }
-    }
-  }
-
-}
diff --git a/core/modules/link/src/Plugin/Validation/Constraint/LinkTypeConstraint.php b/core/modules/link/src/Plugin/Validation/Constraint/LinkTypeConstraint.php
index a62dd62..79a6e28 100644
--- a/core/modules/link/src/Plugin/Validation/Constraint/LinkTypeConstraint.php
+++ b/core/modules/link/src/Plugin/Validation/Constraint/LinkTypeConstraint.php
@@ -8,7 +8,6 @@
 namespace Drupal\link\Plugin\Validation\Constraint;
 
 use Drupal\link\LinkItemInterface;
-use Drupal\link\Plugin\Field\FieldWidget\LinkWidget;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\ConstraintValidatorInterface;
 use Symfony\Component\Validator\ExecutionContextInterface;
@@ -76,7 +75,7 @@ public function validate($value, Constraint $constraint) {
       }
 
       if (!$uri_is_valid) {
-        $this->context->addViolation($this->message, array('@uri' => LinkWidget::getUriAsDisplayableString($link_item->uri)));
+        $this->context->addViolation($this->message, array('@uri' => $link_item->uri));
       }
     }
   }
diff --git a/core/modules/link/src/Tests/LinkFieldTest.php b/core/modules/link/src/Tests/LinkFieldTest.php
index b8ad326..28bd87c 100644
--- a/core/modules/link/src/Tests/LinkFieldTest.php
+++ b/core/modules/link/src/Tests/LinkFieldTest.php
@@ -137,14 +137,18 @@ function testURLValidation() {
     $validation_error_1 = "The path '@link_path' is invalid.";
     $validation_error_2 = 'Manually entered paths should start with /, ? or #.';
     $invalid_external_entries = array(
+      // Missing protcol
+      'not-an-url' => $validation_error_2,
       // Invalid protocol
       'invalid://not-a-valid-protocol' => $validation_error_1,
       // Missing host name
       'http://' => $validation_error_1,
     );
-    // We allow URIs not pointing to Drupal (yet), so site builders can build
-    // their information architecture before they built their actual site.
-    $invalid_internal_entries = [];
+    $invalid_internal_entries = array(
+      '/non/existing/path' => $validation_error_1,
+      'no-leading-slash' => $validation_error_2,
+      'entity:non_existing_entity_type/yar' => $validation_error_1,
+    );
 
     // Test external and internal URLs for 'link_type' = LinkItemInterface::LINK_GENERIC.
     $this->assertValidEntries($field_name, $valid_external_entries + $valid_internal_entries);
@@ -161,14 +165,6 @@ function testURLValidation() {
     $this->field->save();
     $this->assertValidEntries($field_name, $valid_internal_entries);
     $this->assertInvalidEntries($field_name, $valid_external_entries + $invalid_internal_entries);
-
-    // Ensure that users with 'link to any page', don't apply access checking.
-    $this->drupalLogin($this->drupalCreateUser([
-      'view test entity',
-      'administer entity_test content',
-    ]));
-    $this->assertValidEntries($field_name, ['entity_test/add']);
-    $this->assertInValidEntries($field_name, ['admin']);
   }
 
   /**
diff --git a/core/modules/menu_ui/src/Tests/MenuTest.php b/core/modules/menu_ui/src/Tests/MenuTest.php
index 4d56a77..c38f25f 100644
--- a/core/modules/menu_ui/src/Tests/MenuTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuTest.php
@@ -639,13 +639,18 @@ function addMenuLink($parent = '', $path = '/', $menu_name = 'tools', $expanded
    * Attempts to add menu link with invalid path or no access permission.
    */
   function addInvalidMenuLink() {
-    foreach (array('access' => '/admin/people/permissions') as $type => $link_path) {
+    foreach (array('valid' => '/-&-', 'access' => '/admin/people/permissions') as $type => $link_path) {
       $edit = array(
         'link[0][uri]' => $link_path,
         'title[0][value]' => 'title',
       );
       $this->drupalPostForm("admin/structure/menu/manage/{$this->menu->id()}/add", $edit, t('Save'));
-      $this->assertRaw(t("The path '@link_path' is inaccessible.", array('@link_path' => $link_path)), 'Menu link was not created');
+      if ($type === 'access') {
+        $this->assertRaw(t("The path '@link_path' is inaccessible.", array('@link_path' => $link_path)), 'Menu link was not created');
+      }
+      else {
+        $this->assertRaw(t("The path '@link_path' is invalid.", array('@link_path' => $link_path)), 'Menu link was not created');
+      }
     }
   }
 
