When an Excel user right-clicks a cell and chooses Insert Comment in older builds — or Insert Note in current ones — the workbook gains entries in two cooperating XML parts. The first is xl/comments1.xml, which stores the note text, the cell reference, and an <authors> table that records every commenter name verbatim. The second is xl/drawings/vmlDrawing1.vml, a fragment of vintage Vector Markup Language that describes the floating yellow note box: its size, its anchor, its colours, and crucially whether it is shown or hidden. This is the legacy comment system — distinct from the modern threaded comments stored in xl/threadedComments/ — and it is still produced, still hidden by default, and still routinely shipped with the original author’s name attached. This post walks through where the layer lives, what each part leaks, why hidden notes are not gone, why deletion orphans shapes and authors, and how to actually strip both parts before workbooks leave the perimeter.
Modern Excel ships two parallel comment systems, and they store their data in completely different places. The newer one — covered in detail in our piece on threaded comments and persona IDs — writes conversational replies to xl/threadedComments/ and resolves each commenter to a Microsoft 365 identity in xl/persons/person.xml. The older one, which Microsoft now labels Notes in the ribbon but which the file format still calls comments, predates co-authoring entirely. It stores its text in xl/comments1.xml and the geometry of its yellow pop-up box in xl/drawings/vmlDrawing1.vml. The two systems are not mutually exclusive: a single workbook frequently carries both, because notes created years ago in a desktop build sit alongside threaded comments added later in the browser.
The legacy layer matters for metadata hygiene because almost everyone has forgotten it exists under its old name. Cleanup advice that says “remove the threaded comments” misses it entirely. Document Inspector treats it as a separate category. And because notes are hidden by default — they only appear when you hover the little red triangle in a cell corner — authors routinely leave candid remarks in them under the assumption that no recipient will ever look.
What the current ribbon calls a Note is what the XLSX format calls a comment, stored in xl/comments*.xml. What the ribbon calls a Comment is the newer threaded system in xl/threadedComments/. The naming flipped around 2019; the file format did not. A workbook can carry both, and a cleanup that only knows about one ships the other.
The comments part has a simple, durable structure. It opens with an <authors> table — a flat list of every distinct commenter name — followed by a <commentList> in which each comment references an author by zero-based index and pins itself to a cell:
// xl/comments1.xml — authors table plus comment list
<comments xmlns="...spreadsheetml/2006/main">
<authors>
<author>ACME\j.maller</author>
<author>Priya Desai</author>
<author>External Reviewer (Big Four)</author>
</authors>
<commentList>
<comment ref="D14" authorId="0">
<text><r><t>placeholder — real number is in the CFO copy</t></r></text>
</comment>
<comment ref="F22" authorId="2">
<text><r><t>cannot support this assumption without the underlying contract</t></r></text>
</comment>
</commentList>
</comments>
Three things leak from that one fragment. The authors table records names exactly as Excel captured them — here a Windows domain login (ACME\j.maller), a full personal name, and a self-described external reviewer. The comment text carries candid editorial remarks: an admission that the visible number is a placeholder and the real figure lives in a separate CFO copy, and an external auditor refusing to support an assumption. And the authorId index ties each remark to a specific person, so a reader can attribute every note even though the rendered comment box usually shows only the text.
The <authors> list captures the name Excel had for each commenter at the moment the note was created — a domain login, a display name, or whatever was typed into the username field. It survives independently of the comment text and is the single most reliable identity artefact in the legacy layer. Even a workbook whose notes look anonymous in the UI names every contributor in plain XML.
The comment text alone is not a renderable note — Excel needs to know where the yellow box sits, how big it is, and whether it is currently visible. That information lives in a separate, much older format: Vector Markup Language, a pre-SVG vector dialect Microsoft retired everywhere else but kept alive specifically for legacy comments. Each note has a matching <v:shape> in xl/drawings/vmlDrawing1.vml:
// xl/drawings/vmlDrawing1.vml — the floating note box
<v:shape type="#_x0000_t202" style="...visibility:hidden">
<v:fill color2="#ffffe1"/>
<x:ClientData ObjectType="Note">
<x:MoveWithCells/>
<x:SizeWithCells/>
<x:Anchor>3, 15, 13, 4, 6, 31, 16, 1</x:Anchor>
<x:AutoFill>False</x:AutoFill>
<x:Row>13</x:Row>
<x:Column>3</x:Column>
</x:ClientData>
</v:shape>
The visibility:hidden in the style string is the toggle behind Show/Hide Comment. The <x:Row> and <x:Column> values are the zero-based anchor cell, so the VML shape independently records which cell a note belongs to even when the comments part is read separately. The <x:Anchor> tuple is the box geometry in column/row/offset units. None of this is the note text, but all of it is metadata: it tells a reader the layer exists, how many notes there are, which cells they target, and whether the author left them visible or tucked away.
The defining property of a legacy note is that it is hidden by default. A cell with a note shows only a small red triangle in its top-right corner; the box appears on hover or when the author explicitly pins it open with Show Comment. Authors internalise this as “the note is out of the way” and write accordingly. But hiding a note flips a single visibility attribute in the VML shape. The text in xl/comments1.xml is identical whether the box is shown or hidden. From a metadata-extraction standpoint, the show/hide state is irrelevant: a script reads the text the same way regardless.
This produces a predictable failure mode. A reviewer scrolls a worksheet, sees no open comment boxes, concludes the sheet has no notes, and ships it. The red triangles are easy to miss against busy formatting, and on a sheet with frozen panes or hidden rows they may not be visible at all. Meanwhile the comments part holds every candid remark anyone ever attached. The same pattern recurs across the format — it is the comment-layer equivalent of the shared-strings table preserving deleted cell contents: invisible in the grid, fully present in the XML.
Hide Comment sets visibility:hidden on the VML shape and nothing else. The note text stays byte-for-byte in xl/comments*.xml. Reviewing a workbook visually will never surface a hidden note; only reading the comments part will. Treat every red triangle — and every note you cannot see — as text on its way to the recipient.
Because notes feel ephemeral, they collect the candid commentary that never makes it into a cell. Across real-world workbooks the recurring categories are remarkably consistent:
The metadata value is that notes are written in a register no one uses for cell content. They are unguarded. A reader who extracts the comments part of a deal model frequently learns more about how much the author trusts their own numbers than they would from any amount of formula auditing.
Deleting a note is a two-part operation that Excel does not always complete cleanly. Removing the comment should drop the <comment> element from xl/comments1.xml and the matching <v:shape> from the VML drawing. In practice several workflows leave one half behind. Round-tripping through a third-party library, copy-pasting cells with notes between sheets, or editing in one application and saving in another can leave a VML shape with no corresponding comment, or — more usefully to an investigator — an author entry in the <authors> table that no surviving comment references.
An orphan author is durable evidence that a contributor once left a note that has since been deleted. Excel almost never compacts the authors table, because author indices are positional — removing an entry would renumber every comment that follows. So the safe behaviour, and the one Excel usually takes, is to leave the deleted commenter’s name in the table forever. A workbook whose visible notes are all from one person can carry an authors table listing five, quietly documenting four reviewers whose comments were removed.
// authors table retains names no surviving comment references
<authors>
<author>Priya Desai</author> <!-- authorId 0, used -->
<author>ACME\d.okafor</author> <!-- authorId 1, ORPHAN -->
<author>contractor_temp</author> <!-- authorId 2, ORPHAN -->
</authors>
Because author indices are positional, Excel leaves deleted commenters in the <authors> table rather than renumbering. A workbook that looks like it has one reviewer can name every person who ever touched the notes — including contractors and people who have since left. Compare the indices used by surviving comments against the full authors list to find the orphans.
Three relationships hold the layer together, and any cleanup has to respect all three or it produces a workbook Excel complains about on open. The worksheet’s rels file (xl/worksheets/_rels/sheet1.xml.rels) carries a relationship of type comments pointing at ../comments1.xml and a relationship of type vmlDrawing pointing at ../drawings/vmlDrawing1.vml. The worksheet XML itself carries a <legacyDrawing r:id="..."/> element that names the VML relationship. And [Content_Types].xml declares the content types for both the comments part and the vml default extension.
This four-point wiring — comments part, VML part, two rels entries, the <legacyDrawing> pointer, and the content-type registrations — is why amateur cleanup tends to break files. Delete the comments part but leave the rels entry, and Excel reports the workbook as corrupt and offers to repair it. Leave the VML part but delete the comments, and the red triangles vanish while the orphan shapes linger. Reliable removal walks all of these in one coordinated pass, exactly as the hyperlink layer requires touching both the worksheet block and its rels file.
Enumerating legacy notes needs only a ZIP reader and an XML parser. Walking every xl/comments*.xml part and joining each comment to its author by index produces an attributed list of every note in the workbook:
# dump every legacy note with its author and cell
import zipfile, re
from lxml import etree
SS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
with zipfile.ZipFile("workbook.xlsx") as z:
for name in z.namelist():
if not re.match(r"xl/comments\d+\.xml", name):
continue
tree = etree.fromstring(z.read(name))
authors = [a.text for a in tree.iter(f"{{SS}}author")]
for c in tree.iter(f"{{SS}}comment"):
who = authors[int(c.get("authorId"))]
txt = "".join(c.itertext()).strip()
print(c.get("ref"), who, repr(txt))
The script prints one line per note: the cell, the resolved author name, and the text. To surface orphan authors, diff the set of indices actually used by comments against range(len(authors)) — any index never used is a deleted commenter still named in the table. For ad-hoc inspection, renaming the file to .zip, expanding it, and grepping xl/comments*.xml for <author> and <t> surfaces the whole layer in seconds — which is exactly what an opportunistic recipient does the moment a workbook lands.
From a single sweep through the legacy comment layer of a moderately-used workbook, a reader typically extracts:
<authors> table, frequently including domain logins that reveal the username convention.ref attributes.visibility flags — a hint at how private the author believed them to be.The first four categories are identity and candid content; the last three are process and timeline. Together they routinely reveal more about how a workbook was built — and how much its author trusted it — than the cell values do.
Microsoft’s Document Inspector does have a Comments and Annotations check, and on the desktop it will remove legacy notes when run. But the coverage has well-known gaps. The check is a separate item from the threaded-comments check, so users who clear one frequently believe they have cleared both. On Mac builds and in several online and mobile contexts the comment-removal scope differs from the Windows desktop, and notes that one platform strips another leaves in place — the same cross-platform inconsistency we documented for Document Inspector gaps between Mac and Windows. And the inspector operates on the workbook as Excel models it in memory; orphan VML shapes and orphan author entries that Excel no longer associates with a live comment are not always part of that model and can survive the pass.
The result matches the pattern across the whole format: the inspector handles the headline case — visible notes attached to live comments — and trusts the user not to care about the residue. A workbook “inspected and cleaned” routinely still ships orphan author names and orphan VML shapes, and a workbook cleaned of Comments in the modern sense routinely still ships every legacy Note.
Clearing threaded comments does nothing to legacy notes, and vice versa. Document Inspector treats them as separate checks, splits coverage across platforms, and does not reliably reach orphan shapes or orphan author entries. If your share workflow stops at one inspector pass, assume the other comment layer — and its residue — is still in the file.
Reliable cleanup operates at the package level and removes all four wiring points in one coordinated pass. For a workbook bound for external release the minimum sweep deletes every xl/comments*.xml part, deletes every xl/drawings/vmlDrawing*.vml part that exists solely to back notes, removes the comments and vmlDrawing relationships from each worksheet’s rels file, removes the <legacyDrawing> element from each worksheet, and drops the now-unused content-type declarations from [Content_Types].xml:
# remove the legacy comment layer end-to-end
# 1. drop every xl/comments*.xml part
# 2. drop every note-only xl/drawings/vmlDrawing*.vml part
# 3. delete Type=".../comments" and Type=".../vmlDrawing"
# relationships from each xl/worksheets/_rels/sheet*.xml.rels
# 4. remove the <legacyDrawing r:id="..."/> element from each
# xl/worksheets/sheet*.xml
# 5. drop the now-orphan Override/Default entries from
# [Content_Types].xml so the package validates
# Excel then opens the workbook with no notes and no repair prompt.
A subtle point: some vmlDrawing parts back more than notes — legacy form controls and other annotations can share the same VML file. A safe pass parses each VML part, removes only the shapes whose <x:ClientData ObjectType="Note"> marks them as comments, and keeps the part if other shapes remain. Blindly deleting every VML file can strip checkboxes and option buttons a worksheet legitimately needs.
For workbooks where some notes must stay — an internal instruction sheet that genuinely relies on them — the cleanup should at minimum rewrite the <authors> table to a single neutral label and compact it so no orphan names survive, then re-point every surviving comment’s authorId at that one entry. That removes the identity layer while preserving the editorial text the recipient is meant to read.
xl/comments*.xml part and read every note’s text — including notes that are hidden in the grid.<authors> table; confirm no domain logins, personal names, or external-reviewer labels remain.vmlDrawing*.vml part for note shapes and for unrelated form controls before deleting the file.comments and vmlDrawing relationships, the <legacyDrawing> elements, and the matching content-type entries together.The legacy comment layer interlocks with several siblings that should be touched in the same pass. The threaded-comment and persona layer is the modern counterpart and carries its own, tenant-resolvable identities; a workbook is not comment-clean until both are handled. The shared-strings table can retain the text of a note even after the comment is removed, if the note text was ever promoted into a cell. And the same author names that fill the comments table also appear in defined names, in VBA project metadata, and in the core document properties — stripping one source of a name while leaving the others is no cleanup at all.
The broader lesson is the one this whole series keeps returning to: a workbook is a package of cooperating parts, and metadata lives in the seams between them. The legacy comment layer is one of the oldest of those seams, easy to forget precisely because Microsoft renamed it, and reliably overlooked by anyone who thinks “comments” means only the modern threaded kind.
Legacy notes look like a quaint, almost obsolete feature — little yellow boxes that pop up on hover. In metadata terms they are one of the most candid layers a workbook carries. The <authors> table names everyone who annotated the file. The note text records the doubts, disagreements, and warnings the author would never write into a cell. The VML visibility flags show which of those remarks the author thought they had tucked away. Orphan authors preserve the names of reviewers whose notes were deleted. None of it appears in the rendered grid unless you hover the right cell; all of it is in the XML as plain UTF-8, trivially extractable with a ZIP reader and a ten-line script.
For workbooks staying inside an organisation, notes are exactly what they were designed to be: a lightweight way to leave context next to a number. For workbooks crossing the perimeter, they are a confessional the author forgot to lock. The only durable defence is to rewrite the layer as part of a coordinated cleanup that removes the comments part, the VML shapes, the rels entries, the legacy-drawing pointers, and the content-type registrations together — and to remember that in this format a “Note” is just a comment that learned to hide.
Use MetaData Analyzer to enumerate every legacy note across every worksheet, resolve each one to its author, surface hidden note boxes that visual review never shows, detect orphan author names left by deleted comments, and confirm both the legacy and threaded comment layers are empty before your workbooks leave the organisation.
The modern counterpart to legacy notes — the threaded-comment layer that resolves each commenter to a tenant identity in a parallel persona file.
The same invisible-in-the-grid, fully-present-in-the-XML pattern — deleted note text and deleted cell values both linger in plain XML.
The practical how-to for finding and removing every comment, note, and revision record before a workbook leaves your organisation.