diff --git a/arkindex/project/elastic.py b/arkindex/project/elastic.py
index 896368c525608f8597388f01338b23890dc5ce57..2ca1c9ac55b4894b0bba4b1399c1b8679c843d92 100644
--- a/arkindex/project/elastic.py
+++ b/arkindex/project/elastic.py
@@ -109,7 +109,10 @@ class ESElement(Document):
     def from_model(cls, instance):
         from arkindex.documents.models import Element, Transcription
 
-        hidden_children = Element.objects.get_descending(instance.id).filter(type__hidden=True)
+        hidden_children = Element \
+            .objects \
+            .get_descending(instance.id) \
+            .filter(type__hidden=True, zone__isnull=False)
         transcriptions = chain(
             instance.transcriptions.all(),
             *[
diff --git a/arkindex/project/tests/test_elastic.py b/arkindex/project/tests/test_elastic.py
index 915dcac76d97285f07f32006419cd9bc16c93589..0e819f10658f8822a8549b6a0673196a0ba841b2 100644
--- a/arkindex/project/tests/test_elastic.py
+++ b/arkindex/project/tests/test_elastic.py
@@ -1,7 +1,9 @@
 from unittest.mock import patch
-from arkindex_common.enums import MetaType
+from arkindex_common.enums import MetaType, TranscriptionType
 from arkindex.project.tests import FixtureAPITestCase
+from arkindex.project.polygon import Polygon
 from arkindex.project.elastic import ESElement
+from arkindex.documents.models import DataSource
 from arkindex.documents.dates import DateType, InterpretedDate
 
 
@@ -43,3 +45,24 @@ class TestESDocuments(FixtureAPITestCase):
         element.metadatas.create(type=MetaType.Reference, name='ref.', value='123ABC')
         es_document = ESElement.from_model(element)
         self.assertCountEqual(es_document.references, ['123abc'])
+
+    def test_hidden_no_zone(self):
+        """
+        Ensure hidden elements without zones are ignored when indexing an element's hidden children
+        """
+        page = self.corpus.elements.get(name='Volume 1, page 1r')
+        self.assertTrue(page.transcriptions.exists())
+        surface = self.corpus.elements.create(
+            type=self.corpus.types.get(slug='surface'),
+            name='/dev/null',
+            zone=None,
+        )
+        surface.add_parent(page)
+        surface.transcriptions.create(
+            type=TranscriptionType.Word,
+            text='invisible transcription',
+            zone=page.zone.image.zones.create(polygon=Polygon.from_coords(0, 0, 1, 1)),
+            source=DataSource.objects.get(slug='test'),
+        )
+        texts = [tr['text'] for tr in ESElement.from_model(page).to_dict()['transcriptions']]
+        self.assertNotIn('invisible transcription', texts)