diff --git a/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionParser.php b/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionParser.php
index 10b9441c1a28e596cb20e320edd9f7936564db51..ce1aa0c083e115c65e21ba8335423640fc110291 100644
--- a/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionParser.php
+++ b/core/lib/Drupal/Component/Annotation/Doctrine/StaticReflectionParser.php
@@ -205,7 +205,7 @@ protected function parse()
                     break;
                 case T_CLASS:
                     // Convert the attributes to fully qualified names.
-                    $this->classAttributes = array_map(fn($name) => strtolower($this->fullySpecifyName($name)), $attributeNames);
+                    $this->classAttributes = array_map(fn($name) => $this->fullySpecifyName($name), $attributeNames);
                     if ($last_token !== T_PAAMAYIM_NEKUDOTAYIM && $last_token !== T_NEW) {
                         $this->docComment['class'] = $docComment;
                         $docComment                = '';
@@ -346,7 +346,13 @@ public function getStaticReflectionParserForDeclaringClass($type, $name)
     public function hasClassAttribute(string $attribute): bool
     {
         $this->parse();
-        return in_array('\\' . ltrim(strtolower($attribute), '\\'), $this->classAttributes, TRUE);
+        foreach ($this->classAttributes as $classAttribute) {
+            if (is_a($classAttribute, $attribute, TRUE)) {
+                return TRUE;
+            }
+        }
+
+        return FALSE;
     }
 
     /**
diff --git a/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/Attribute/Nonexistent.php b/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/Attribute/Nonexistent.php
new file mode 100644
index 0000000000000000000000000000000000000000..45ed519aa40da8a60867f6d54203b4e13501ed2b
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/Attribute/Nonexistent.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace Drupal\Tests\Component\Annotation\Doctrine\Fixtures\Attribute;
+
+// @phpstan-ignore-next-line
+#[NonexistentAttribute]
+final class Nonexistent
+{
+}
diff --git a/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/ExtraAttributes/ExampleAttribute.php b/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/ExtraAttributes/ExampleAttribute.php
index 0275fabb56f80042ee169b920c2788f732848435..abcd69fa12918af9c65ac4045b72a3571eed91b7 100644
--- a/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/ExtraAttributes/ExampleAttribute.php
+++ b/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/ExtraAttributes/ExampleAttribute.php
@@ -3,6 +3,6 @@
 namespace Drupal\Tests\Component\Annotation\Doctrine\Fixtures\ExtraAttributes;
 
 #[\Attribute]
-final class ExampleAttribute
+final class ExampleAttribute extends ExampleParentAttribute
 {
 }
diff --git a/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/ExtraAttributes/ExampleParentAttribute.php b/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/ExtraAttributes/ExampleParentAttribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea1eaaa0f89afe12683552ab30dd391c5a3589c1
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Annotation/Doctrine/Fixtures/ExtraAttributes/ExampleParentAttribute.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Drupal\Tests\Component\Annotation\Doctrine\Fixtures\ExtraAttributes;
+
+#[\Attribute]
+class ExampleParentAttribute {
+
+}
diff --git a/core/tests/Drupal/Tests/Component/Annotation/Doctrine/StaticReflectionParserTest.php b/core/tests/Drupal/Tests/Component/Annotation/Doctrine/StaticReflectionParserTest.php
index d929e48f6120b1cd902c38b818d61811e30335a9..85a99f3c353b6ee12467905c74629937385bead0 100644
--- a/core/tests/Drupal/Tests/Component/Annotation/Doctrine/StaticReflectionParserTest.php
+++ b/core/tests/Drupal/Tests/Component/Annotation/Doctrine/StaticReflectionParserTest.php
@@ -15,8 +15,10 @@ class StaticReflectionParserTest extends TestCase {
 
   /**
    * @testWith ["AttributeClass", "\\Attribute", true]
+   *           ["AttributeClass", "attribute", true]
    *           ["AttributeClass", "Attribute", true]
    *           ["AttributeClass", "\\DoesNotExist", false]
+   *           ["Nonexistent", "NonexistentAttribute", false]
    *           ["MultipleAttributes", "Attribute", true]
    *           ["MultipleAttributes", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\Attribute\\AttributeClass", true]
    *           ["MultipleAttributes", "DoesNotExist", false]
@@ -26,15 +28,16 @@ class StaticReflectionParserTest extends TestCase {
    *           ["UsedAsQualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleAttribute", true]
    *           ["Qualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleAttribute", true]
    *           ["Relative", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\Attribute\\SubDir\\SubDirAttribute", true]
+   *           ["FullyQualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
+   *           ["Used", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
+   *           ["UsedAs", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
+   *           ["UsedAsQualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
+   *           ["Qualified", "Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\ExtraAttributes\\ExampleParentAttribute", true]
    */
   public function testAttribute(string $class, string $attribute_class, bool $expected) {
     $finder = MockFileFinder::create(__DIR__ . '/Fixtures/Attribute/' . $class . '.php');
     $parser = new StaticReflectionParser('\\Drupal\\Tests\\Component\\Annotation\\Doctrine\\Fixtures\\Attribute\\' . $class, $finder);
-    $this->assertSame($expected, $parser->hasClassAttribute($attribute_class), "'$class' has '$attribute_class'");
-    // Attribute names and namespaces are case-insensitive in PHP. Practically
-    // Composer autoloading makes this untrue but builtins like \Attribute are
-    // case-insensitive so we should support that.
-    $this->assertSame($expected, $parser->hasClassAttribute(strtoupper($attribute_class)), "'$class' has '$attribute_class'");
+    $this->assertSame($expected, $parser->hasClassAttribute($attribute_class), "'$class' has attribute that is a '$attribute_class'");
   }
 
 }