diff --git a/core/modules/field/config/schema/field.schema.yml b/core/modules/field/config/schema/field.schema.yml
index cdd1d4bab05cbeba55c7f2abc1aa80a567ded688..26f98da302f203ca3a1e6ffde1b6f232b05ccb7b 100644
--- a/core/modules/field/config/schema/field.schema.yml
+++ b/core/modules/field/config/schema/field.schema.yml
@@ -45,6 +45,10 @@ field.storage.*.*:
     cardinality:
       type: integer
       label: 'Maximum number of values users can enter'
+      constraints:
+        NoEntitiesExistYetWithHigherCardinality:
+          entityType: '%parent.entity_type'
+          fieldName: '%parent.field_name'
     translatable:
       type: boolean
       label: 'Translatable'
diff --git a/core/modules/field/src/Plugin/Validation/Constraint/NoEntitiesExistYetWithHigherCardinality.php b/core/modules/field/src/Plugin/Validation/Constraint/NoEntitiesExistYetWithHigherCardinality.php
new file mode 100644
index 0000000000000000000000000000000000000000..88b976e568acf8414934e47dc15ac14c4563e1d9
--- /dev/null
+++ b/core/modules/field/src/Plugin/Validation/Constraint/NoEntitiesExistYetWithHigherCardinality.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\field\Plugin\Validation\Constraint;
+
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Symfony\Component\Validator\Constraint as SymfonyConstraint;
+use Drupal\Core\Validation\Attribute\Constraint;
+
+/**
+ * Checks if an entity with a higher cardinality than specified exists.
+ */
+#[Constraint(
+  id: 'NoEntitiesExistYetWithHigherCardinality',
+  label: new TranslatableMarkup('No entities exist with higher cardinality', [], ['context' => 'Validation'])
+)]
+class NoEntitiesExistYetWithHigherCardinality extends SymfonyConstraint {
+
+  /**
+   * The error message if an entity with a higher cardinality exists.
+   *
+   * @var string
+   */
+  public string $message = "The field '@field_name' of entity type '@entity_type' has more entries (@max_delta) than the cardinality (@cardinality) allows.";
+
+  /**
+   * The entity type to check.
+   *
+   * @var string
+   */
+  public string $entityType;
+
+  /**
+   * The field name to check.
+   *
+   * @var string
+   */
+  public string $fieldName;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRequiredOptions(): array {
+    return ['entityType', 'fieldName'];
+  }
+
+}
diff --git a/core/modules/field/src/Plugin/Validation/Constraint/NoEntitiesExistYetWithHigherCardinalityValidator.php b/core/modules/field/src/Plugin/Validation/Constraint/NoEntitiesExistYetWithHigherCardinalityValidator.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2dd2dbf5b5259dc2e47916676205341d7e215a0
--- /dev/null
+++ b/core/modules/field/src/Plugin/Validation/Constraint/NoEntitiesExistYetWithHigherCardinalityValidator.php
@@ -0,0 +1,114 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\field\Plugin\Validation\Constraint;
+
+use Drupal\Core\Config\Schema\TypeResolver;
+use Drupal\Core\Database\DatabaseExceptionWrapper;
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\Core\TypedData\TypedDataInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Validator\Constraint as SymfonyConstraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * Validates the NoEntitiesExistYetWithHigherCardinality constraint.
+ *
+ * This validator checks whether existing entities of a specified type have more
+ * field values than allowed by the given cardinality limit. It performs an
+ * aggregate query to find the maximum delta (number of field values) for the
+ * specified field across all entities of the given type, and compares it
+ * against the provided cardinality.
+ *
+ * The validation:
+ * - Skips if cardinality is unlimited (-1)
+ * - Skips if the field storage configuration doesn't exist
+ * - Uses EntityTypeManager to query the maximum field delta
+ * - Adds a violation if the maximum delta exceeds the cardinality
+ *
+ * This validator implements ContainerInjectionInterface to access the entity
+ * type manager service from the Drupal service container.
+ *
+ * @see \Drupal\field\Plugin\Validation\Constraint\NoEntitiesExistYetWithHigherCardinality
+ */
+class NoEntitiesExistYetWithHigherCardinalityValidator extends ConstraintValidator implements ContainerInjectionInterface {
+
+  public function __construct(
+    protected EntityTypeManagerInterface $entityTypeManager,
+  ) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container): self {
+    return new static(
+      $container->get('entity_type.manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate(mixed $cardinality, SymfonyConstraint $constraint): void {
+    assert($constraint instanceof NoEntitiesExistYetWithHigherCardinality);
+
+    if ($cardinality === FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
+      return;
+    }
+
+    $object = $this->context->getObject();
+    assert($object instanceof TypedDataInterface);
+
+    $entity_type = TypeResolver::resolveExpression($constraint->entityType, $object);
+    $field_name = TypeResolver::resolveExpression($constraint->fieldName, $object);
+
+    // We cannot check this constraint if the field storage does not exist.
+    $fieldStorageConfig = $this->entityTypeManager->getStorage('field_storage_config')
+      ->load($entity_type . '.' . $field_name);
+    if ($fieldStorageConfig === NULL) {
+      return;
+    }
+
+    if ($fieldStorageConfig->hasCustomStorage()) {
+      // If the field storage has custom storage, we cannot check this
+      // constraint.
+      return;
+    }
+
+    $max_delta_alias = 'max_delta';
+    $query = $this->entityTypeManager->getStorage($entity_type)
+      ->getAggregateQuery()
+      ->accessCheck(FALSE)
+      ->aggregate($field_name . '.%delta', 'MAX', NULL, $max_delta_alias);
+
+    // When the schema for the entity does not exist the query will throw an
+    // exception. This should only happen in tests.
+    // @see https://www.drupal.org/node/3475719
+    // @todo Remove in Drupal 12.
+    try {
+      $result = $query->execute();
+    }
+    catch (DatabaseExceptionWrapper) {
+      return;
+    }
+
+    $max_delta = 0;
+    if (is_array($result) && !empty($result)) {
+      $max_delta = $result[0][$max_delta_alias] ?? 0;
+    }
+
+    if ($max_delta > $cardinality) {
+      $this->context->addViolation($constraint->message, [
+        '@entity_type' => $entity_type,
+        '@field_name' => $field_name,
+        '@max_delta' => $max_delta,
+        '@cardinality' => $cardinality,
+      ]);
+    }
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/Plugin/Validation/Constraint/NoEntitiesExistYetWithHigherCardinalityTest.php b/core/modules/field/tests/src/Unit/Plugin/Validation/Constraint/NoEntitiesExistYetWithHigherCardinalityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a612d4c4a726c9a9df9414b7242733fef6219c16
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/Plugin/Validation/Constraint/NoEntitiesExistYetWithHigherCardinalityTest.php
@@ -0,0 +1,124 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\field\Unit\Plugin\Validation\Constraint;
+
+use Drupal\field\Plugin\Validation\Constraint\NoEntitiesExistYetWithHigherCardinality;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\Validator\Exception\MissingOptionsException as MissingOptionsExceptionAlias;
+
+/**
+ * Tests the NoEntitiesExistYetWithHigherCardinality constraint.
+ *
+ * @group field
+ */
+class NoEntitiesExistYetWithHigherCardinalityTest extends UnitTestCase {
+
+  /**
+   * Tests the constraint's required options.
+   */
+  public function testRequiredOptions(): void {
+    $options = [
+      'entityType' => 'node',
+      'fieldName' => 'field_test',
+    ];
+    $constraint = new NoEntitiesExistYetWithHigherCardinality($options);
+    $requiredOptions = $constraint->getRequiredOptions();
+
+    $this->assertTrue(is_array($requiredOptions));
+    $this->assertEquals(['entityType', 'fieldName'], $requiredOptions);
+  }
+
+  /**
+   * Tests the constraint initialization with valid options.
+   */
+  public function testValidOptions(): void {
+    $options = [
+      'entityType' => 'node',
+      'fieldName' => 'field_test',
+    ];
+
+    $constraint = new NoEntitiesExistYetWithHigherCardinality($options);
+
+    $this->assertEquals('node', $constraint->entityType);
+    $this->assertEquals('field_test', $constraint->fieldName);
+    $this->assertEquals(
+      "The field '@field_name' of entity type '@entity_type' has more entries (@max_delta) than the cardinality (@cardinality) allows.",
+      $constraint->message
+    );
+  }
+
+  /**
+   * Tests the constraint initialization with missing required options.
+   */
+  public function testMissingOptions(): void {
+    $this->expectException(MissingOptionsExceptionAlias::class);
+    $this->expectExceptionMessage('The options "entityType" must be set for constraint');
+
+    new NoEntitiesExistYetWithHigherCardinality(['fieldName' => 'field_test']);
+  }
+
+  /**
+   * Tests the constraint's default configuration.
+   */
+  public function testDefaultConfiguration(): void {
+    $options = [
+      'entityType' => 'user',
+      'fieldName' => 'field_example',
+    ];
+
+    $constraint = new NoEntitiesExistYetWithHigherCardinality($options);
+
+    $defaultConfig = $constraint->getDefaultOption();
+    $this->assertNull($defaultConfig);
+  }
+
+  /**
+   * Tests the message template with different parameters.
+   *
+   * @dataProvider messageParametersProvider
+   */
+  public function testMessageParameters(string $entityType, string $fieldName, int $maxDelta, int $cardinality, string $expectedMessage): void {
+    $options = [
+      'entityType' => $entityType,
+      'fieldName' => $fieldName,
+    ];
+
+    $constraint = new NoEntitiesExistYetWithHigherCardinality($options);
+
+    // Simulate the violation building process.
+    $parameters = [
+      '@field_name' => $fieldName,
+      '@entity_type' => $entityType,
+      '@max_delta' => (string) $maxDelta,
+      '@cardinality' => (string) $cardinality,
+    ];
+
+    $message = strtr($constraint->message, $parameters);
+    $this->assertEquals($expectedMessage, $message);
+  }
+
+  /**
+   * Data provider for testMessageParameters.
+   */
+  public static function messageParametersProvider(): array {
+    return [
+      [
+        'node',
+        'field_body',
+        3,
+        2,
+        "The field 'field_body' of entity type 'node' has more entries (3) than the cardinality (2) allows.",
+      ],
+      [
+        'user',
+        'field_address',
+        5,
+        1,
+        "The field 'field_address' of entity type 'user' has more entries (5) than the cardinality (1) allows.",
+      ],
+    ];
+  }
+
+}