diff --git a/pelican/contents.py b/pelican/contents.py
index a06a1a6a..82da413a 100644
--- a/pelican/contents.py
+++ b/pelican/contents.py
@@ -27,6 +27,7 @@ from pelican.utils import (
     sanitised_join,
     set_date_tzinfo,
     slugify,
+    strip_toc_elements_from_html,
     truncate_html_paragraphs,
     truncate_html_words,
 )
@@ -446,14 +447,20 @@ class Content:
             content = truncate_html_paragraphs(self.content, max_paragraphs)
 
         if self.settings["SUMMARY_MAX_LENGTH"] is None:
-            return content
-
-        return truncate_html_words(
+            summary = content
+        else:
+            summary = truncate_html_words(
             content,
             self.settings["SUMMARY_MAX_LENGTH"],
             self.settings["SUMMARY_END_SUFFIX"],
         )
 
+        # Strip TOC elements that would contain broken links in summary context
+        # TOC anchors only work in full article view, not in summaries/excerpts
+        summary = strip_toc_elements_from_html(summary)
+
+        return summary
+
     @property
     def summary(self) -> str:
         return self.get_summary(self.get_siteurl())
diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py
index 95bf197a..f0b9c32b 100644
--- a/pelican/tests/test_utils.py
+++ b/pelican/tests/test_utils.py
@@ -420,6 +420,60 @@ class TestUtils(LoggedTestCase):
         self.assertEqual(utils.truncate_html_paragraphs(three, 3), three)
         self.assertEqual(utils.truncate_html_paragraphs(three, 4), three)
 
+    def test_strip_toc_elements_from_html(self):
+        # Test removing TOC div with various class names
+        html_with_toc = (
+            '<div class="contents topic" id="table-of-contents">'
+            '<p class="topic-title">Table of Contents</p>'
+            '<ul><li><a href="#section1">Section 1</a></li></ul>'
+            '</div>'
+            '<p>Some content here</p>'
+        )
+        result = utils.strip_toc_elements_from_html(html_with_toc)
+        self.assertNotIn('<div class="contents', result)
+        self.assertIn('<p>Some content here</p>', result)
+
+        # Test removing toc-backref anchors while preserving heading text
+        html_with_backref = (
+            '<h2><a class="toc-backref" href="#id1">Section Heading</a></h2>'
+            '<p>Some content</p>'
+        )
+        result = utils.strip_toc_elements_from_html(html_with_backref)
+        self.assertNotIn('toc-backref', result)
+        self.assertNotIn('<a class=', result)
+        self.assertIn('Section Heading', result)
+        self.assertIn('<h2>Section Heading</h2>', result)
+
+        # Test combined - remove both TOC div and backrefs
+        html_combined = (
+            '<div class="contents">'
+            '<p>TOC here</p>'
+            '</div>'
+            '<h2><a class="toc-backref" href="#id1">the design</a></h2>'
+            '<p>Article content</p>'
+            '<h2><a class="toc-backref" href="#id2">key features</a></h2>'
+            '<p>More content</p>'
+        )
+        result = utils.strip_toc_elements_from_html(html_combined)
+        self.assertNotIn('<div class="contents', result)
+        self.assertNotIn('toc-backref', result)
+        self.assertIn('the design', result)
+        self.assertIn('key features', result)
+        self.assertIn('<p>Article content</p>', result)
+
+        # Test empty input
+        self.assertEqual(utils.strip_toc_elements_from_html(''), '')
+
+        # Test HTML without TOC elements (should be unchanged)
+        plain_html = '<p>Just some plain content</p>'
+        self.assertEqual(utils.strip_toc_elements_from_html(plain_html), plain_html)
+
+        # Test case-insensitive matching
+        html_mixed_case = '<div CLASS="CONTENTS"><p>TOC</p></div><p>Content</p>'
+        result = utils.strip_toc_elements_from_html(html_mixed_case)
+        self.assertNotIn('CONTENTS', result)
+        self.assertIn('<p>Content</p>', result)
+
     def test_process_translations(self):
         fr_articles = []
         en_articles = []
diff --git a/pelican/utils.py b/pelican/utils.py
index eb281ce9..50213bc0 100644
--- a/pelican/utils.py
+++ b/pelican/utils.py
@@ -643,6 +643,36 @@ def truncate_html_paragraphs(s, count):
     return "".join(paragraphs)
 
 
+def strip_toc_elements_from_html(html: str) -> str:
+    """Strip table of contents elements from HTML summaries.
+
+    Removes TOC divs and toc-backref anchor links that would be broken
+    when article summaries are displayed outside of the full article context
+    (e.g., on homepage, in RSS feeds).
+
+    :param html: HTML content to process
+    :return: Cleaned HTML with TOC elements removed
+    """
+    # Remove the entire <div class="contents"> ... </div> block
+    html = re.sub(
+        r'<div\s+class="contents[^"]*"[^>]*>.*?</div>',
+        '',
+        html,
+        flags=re.DOTALL | re.IGNORECASE
+    )
+
+    # Remove anchor links from headings (e.g., <a class="toc-backref" href="#id1">text</a>)
+    # These links point to anchors that don't exist in summary context
+    html = re.sub(
+        r'<a[^>]*class="[^"]*toc-backref[^"]*"[^>]*>(.*?)</a>',
+        r'\1',
+        html,
+        flags=re.DOTALL | re.IGNORECASE
+    )
+
+    return html
+
+
 def process_translations(
     content_list: list[Content],
     translation_id: str | Collection[str] | None = None,
