Back to Blog
Technical

Excel Defined Names and Named Ranges: The Hidden Symbol Table Inside Your Workbook

Every XLSX carries a small, almost invisible directory of references called defined names. Most users only ever see them when typing a friendly name into a formula, but the workbook XML stores far more — hidden names invisible to the Name Manager, references to closed external files on a colleague’s laptop, pointers to deleted sheets, built-in flags from features the user no longer remembers turning on, and labels that quietly explain what the workbook is for. This post walks through where defined names live inside the XLSX, how to read the symbol table the way Excel reads it, what the most common leaks look like in practice, and how to actually clean named-range metadata before a workbook leaves your organization.

Technical Team
May 1, 2026
21 min read

What a Defined Name Actually Is

A defined name is a label attached to a value, a cell range, a formula, a constant, or a chunk of code, scoped either to the workbook as a whole or to a single worksheet. When a user types =TaxRate in a cell, Excel looks up TaxRate in the workbook’s symbol table and substitutes whatever expression is registered there — possibly Sheet1!$B$2, possibly the constant 0.075, possibly a long external reference into another file.

From the user’s perspective, defined names are a convenience: friendlier formulas, easier auditing, fewer hard-coded ranges. From the file’s perspective, the symbol table is one of the most expressive metadata layers in the entire XLSX. Each entry can carry the name itself (often a label that describes intent), an arbitrary expression (often pointing somewhere the recipient was never meant to see), a scope, a comment, a hidden flag, and a flag identifying it as a function or future-function reference.

Why the Symbol Table Is Worth Auditing

The Name Manager in Excel’s ribbon shows visible defined names, but it hides built-in names, names with the visible="false" attribute, and many add-in-managed names. The list of names a recipient can read by unzipping the file is consistently larger — often dramatically larger — than the list the author saw before pressing Save.

Where Defined Names Live in the XLSX

Defined names are written to a single element inside xl/workbook.xml: <definedNames>. Each child <definedName> represents one entry in the symbol table.

// Excerpt from xl/workbook.xml

<definedNames>

<definedName name="TaxRate">Inputs!$B$2</definedName>

<definedName name="_xlnm.Print_Area" localSheetId="0">Sheet1!$A$1:$F$48</definedName>

<definedName name="InternalCostBasis" hidden="1">BackEnd!$D$10:$D$200</definedName>

<definedName name="OldQ4Forecast">'[Q4_Forecast_v17_DRAFT.xlsx]Summary'!$B$5</definedName>

</definedNames>

The element is a single flat list. There is no folder hierarchy and no per-name visibility tree — just attributes on each entry. The interesting attributes are:

AttributeMeaning
nameThe label the user (or Excel) chose. Names beginning with _xlnm. or _xlfn. are reserved.
localSheetIdIf present, scopes the name to a single worksheet (zero-indexed). If absent, the name is workbook-scoped.
hidden1 hides the name from the Name Manager. The name still resolves in formulas and is fully visible in the XML.
functionMarks the name as a user-defined function (typically a VBA Function in vbaProject.bin).
commentFree-text note from the author, often more candid than anything in the cells themselves.
vbProcedure1 if the name resolves to a VBA procedure rather than a range.
publishToServerA flag for Excel Services / SharePoint publishing. Hints the workbook was built for a specific server pipeline.

The text content of each <definedName> element is the refersTo expression: the formula or reference the name evaluates to. Reading those expressions across all names in a workbook is one of the fastest ways to get a map of how the workbook is wired internally and where it touches the outside world.

Hidden Names: The Layer the UI Does Not Show

The hidden="1" attribute is exactly what it sounds like — a single flag that omits the name from the Name Manager dialog. Hidden names typically appear when:

  • Add-ins create scratch storage. Add-ins (Solver, Analysis Toolpak, third-party tools) often store state in hidden defined names so the workbook can be re-opened later with the add-in’s context preserved.
  • Templates define internal mechanics. Corporate templates often hide a long list of named ranges that drive validation lists, dynamic dashboards, or branding constants.
  • Authors deliberately hide internals. A modeler hides DiscountTier1, SalesTeamCommission, or _HighWaterMark behind hidden="1", believing those entries are now invisible.
  • Power Query and Data Model artifacts. Power Query queries appear under _xlnm._FilterDatabase and similar names, and the Data Model adds its own hidden symbols.

Hidden Is a UI Hint, Not a Confidentiality Boundary

The hidden="1" attribute is one byte in the XML. The name, the refersTo expression, and any comment are right next to it as plaintext. Anyone who unzips the XLSX and opens xl/workbook.xml in a text editor reads every hidden name in the workbook in seconds. Hiding a name does not encrypt it; it just stops the Excel UI from listing it.

Built-in Names: _xlnm. and What They Reveal

Names beginning with the prefix _xlnm. are reserved by Excel for built-in features. They are not shown in the Name Manager (the UI suppresses anything starting with the underscore prefix), but they sit in the XML alongside user-created names. The most common built-ins:

Built-in NameWhat It Records
_xlnm.Print_AreaThe exact cell range a user marked for printing — often narrower than the data, because the author cropped to what they intended to publish.
_xlnm.Print_TitlesHeader rows / columns the author wanted repeated on each printed page.
_xlnm._FilterDatabaseThe range AutoFilter currently applies to. Exposes which sheet ranges are treated as “the data” even when the rest of the sheet is decorative.
_xlnm.CriteriaNamed criteria from advanced filters — reveals filter logic the author thought was transient.
_xlnm.DatabaseLegacy “data form” range marker; often points to an older, larger dataset that the visible sheet has since been narrowed from.
_xlnm.Sheet_TitleSheet caption metadata, occasionally used to embed an internal title that differs from the visible tab name.
_xlnm.ExtractRecords the most recent advanced-filter extract destination — sometimes a sheet the author later deleted.

Several built-ins are scoped per worksheet via localSheetId, so a workbook with twelve sheets can carry twelve copies of _xlnm.Print_Area, each with its own range. Reading them as a group is a fast tour of how the author imagined each sheet would look on paper — often narrower than the on-screen data, often pointing to ranges that contain rows the published version was supposed to omit.

The _xlfn. and _xlfn._xlws. Prefixes: Version Fingerprints in Disguise

When a workbook uses a function that did not exist in older Excel versions — XLOOKUP, FILTER, LET, LAMBDA — Excel does not just store the function call. It also writes the function name into formulas with a _xlfn. or _xlfn._xlws. prefix so that older Excel versions can fall back to a cached value rather than crash on the unknown function.

These prefixes are not stored in the <definedNames> element directly — they live in worksheet formulas — but they form a parallel symbol table that gives away the same kind of information. A recipient grepping for _xlfn.LAMBDA across xl/worksheets/ learns the workbook was authored on a Microsoft 365 build with LAMBDA support, which narrows the author’s Excel version dramatically.

// Excerpt from xl/worksheets/sheet1.xml &mdash; a formula leaking version

<c r="G7">

<f>_xlfn.XLOOKUP(F7,Lookups!$A$2:$A$200,Lookups!$B$2:$B$200,"n/a")</f>

<v>42</v>

</c>

Combined with the application fingerprint in docProps/app.xml and the build number in docProps/core.xml, the function prefix narrows the author’s tool stack to a remarkably specific identifier — useful in forensics, occasionally awkward when sharing externally with a vendor that should not know which monthly Office build a customer is on.

External References Inside Defined Names

A defined name’s refersTo expression can point outside the workbook. Three flavors of external reference appear in the symbol table, each with its own metadata payload:

1. Live external workbook references

A name pointing to '[Q4_Forecast_v17_DRAFT.xlsx]Summary'!$B$5 records the source workbook’s filename and the sheet inside it. If the original was on a network share, the path is even longer:

'\\fileserver\Finance\Models\2026\[Forecast_v17_DRAFT.xlsx]Internal'!$B$5

Server hostname, department folder, year, draft suffix, and the “Internal” sheet name all leak through a single name entry.

2. References to closed external workbooks

When a workbook references a closed file via externalLinks, the linked workbook is registered in xl/externalLinks/externalLink1.xml and named in _rels/workbook.xml.rels. Defined names then refer to [1]Summary!$B$5 by index rather than by full path. Reading the symbol table without also reading the externalLinks part hides the actual filename, but reading both together produces a complete map. (Our prior post on External Links covers the externalLinks side in depth.)

3. URL-based references (web queries, online sources)

Defined names sometimes reference web queries through Power Query connections or older “web data” features. The URL embedded in the connection becomes part of the workbook’s metadata, often pointing to internal endpoints (intranet pages, dashboards, REST URLs with embedded API keys). The symbol-table entry is brief; the connection it depends on, in xl/connections.xml, is verbose.

Phantom Names: References to Things That No Longer Exist

Defined names persist in the workbook even after the cells, sheets, or external files they refer to are deleted. Excel does not silently remove an orphaned name; the Name Manager keeps it, marks the refersTo as #REF!, and the entry remains in the XML.

// Phantom names left over from deleted sheets and ranges

<definedName name="Q4DraftLayoffPlan">#REF!</definedName>

<definedName name="LegalReviewComments">#REF!</definedName>

<definedName name="BoardScenario_DoNotShare">#REF!</definedName>

The Name Outlives the Data

Even when the cells, sheet, or source file are completely gone, the name is still in the XML. A reader does not get the data the name pointed to, but they get a long descriptive label that often summarizes what was there: PreLayoff_HeadcountByTeam, Q1_Customers_PaymentsOverdue_DRAFT, M&A_Target_FairValue_2025. The name itself is the leak.

Names That Hold Constants and Formulas Instead of Ranges

A defined name does not have to refer to a cell range. The refersTo expression can be a literal value, an array constant, or an arbitrary formula. This is convenient for the author and informative for the reader.

// Names that store values directly, not just references

<definedName name="DiscountTable">{1000,0.05;5000,0.10;25000,0.18;100000,0.25}</definedName>

<definedName name="ApiKeyHash">"sha256:5d41402abc4b2a76b9719d911017c592"</definedName>

<definedName name="CommissionFormula">=IF(Sales>Quota*1.2,0.12,IF(Sales>Quota,0.08,0.04))</definedName>

<definedName name="_TaxJurisdictions">{"CA","0.0725";"NY","0.04";"TX","0.0625"}</definedName>

These “value names” are particularly common in template-driven workflows and in models that started life as hidden constants someone wanted to keep out of the visible sheet. Once a value is in the symbol table, the visible sheet can be cleared, copied, or replaced — the value persists. Removing the cells is not the same as removing the name.

VBA-Bound Names: Procedures and User-Defined Functions

When a workbook contains VBA, defined names can carry a vbProcedure="1" attribute and a refersTo expression that names a VBA procedure rather than a range. Excel uses these to wire shapes, form controls, and event handlers to code.

The procedure name itself often telegraphs the workbook’s purpose: SubmitForReview, PostToServer, EncryptAndUpload, SendCommissionEmails. A reader who never opens the VBA editor still gets a coarse map of what code lives behind the surface and what external systems it might talk to.

Procedure Names Are a Map of Capabilities

In incident response, the list of procedure-bound defined names is often the first thing investigators read. It identifies entry points, callbacks bound to UI elements, and modules that interact with the network — without needing to parse the VBA bytecode at all. For attackers, the names are also a quick reconnaissance signal: SendInvoicesViaSMTP tells them where the credentials probably are.

Inspecting the Symbol Table of an XLSX

You can audit defined names without ever opening Excel. The XML is plain text inside the ZIP. Three approaches that scale from one-off inspection to bulk pipelines:

# 1. Quick command-line audit

unzip -p workbook.xlsx "xl/workbook.xml" | \

xmllint --xpath '//*[local-name()="definedName"]' -

# 2. Find every external reference in the symbol table

unzip -p workbook.xlsx "xl/workbook.xml" | \

grep -oE '\\\\[^<]*|\[[^<]*\]'

# 3. List names with hidden="1"

unzip -p workbook.xlsx "xl/workbook.xml" | \

grep -oE 'definedName[^>]*hidden="1"[^>]*'

For programmatic processing, openpyxl exposes the symbol table directly:

# Python: enumerate every defined name and flag interesting ones

from openpyxl import load_workbook

wb = load_workbook("workbook.xlsx", read_only=True)

for name in wb.defined_names.values():

flags = []

if name.hidden: flags.append("HIDDEN")

if name.localSheetId is not None: flags.append(f"sheet={name.localSheetId}")

if "[" in (name.value or ""): flags.append("EXTERNAL")

if "#REF" in (name.value or ""): flags.append("ORPHAN")

print(name.name, name.value, flags)

Running this against a typical corporate financial model often produces a list with three to five times more names than the Name Manager showed the author — a dramatic gap between what the user thought they were sharing and what the file actually contains.

What People Actually Leak Through Defined Names

In aggregate, the symbol table is a remarkable cross-section of the workbook’s history and the author’s context. A non-exhaustive list of the kinds of leaks that come up over and over in real audits:

  • Server and share names. External-reference paths embedded in name expressions: \\corp-fs01\Finance\, https://intranet.example.com/team-sales/, OneDrive sync paths with usernames in them.
  • Project codenames and internal product labels. Project_Phoenix_Q3, RipcordFinalRecon, Falcon_v3_pricing. Names rarely get sanitized before sharing.
  • Internal authority levels. CFO_ApprovedDiscount, VP_OverrideThreshold, CEO_FinalSay.
  • Deleted-sheet labels still in the symbol table. PreLayoff_Headcount, Confidential_Customer_Costs, Litigation_Sched_Q2, all marked #REF! but with names intact.
  • Author state-of-mind in comments and labels. Margin_TooLow_DoNotSend, Risk_RedoBeforeAudit, Sales_DoNotShareWithOps.
  • Add-in fingerprints. Names registered by Solver, Analysis Toolpak, third-party valuation libraries, custom corporate add-ins. Each one identifies a tool the author had installed and used in this file.
  • Filenames of upstream workbooks. External references that retain the source filename, draft suffix, and sheet name — often a complete chain from v1 through v17_FINAL_FINAL_v2.

How to Actually Clean Defined Names Before Sharing

The Document Inspector in Excel does not remove most defined names. It removes some hidden names tied to specific features (like Power Query queries) but leaves user-created hidden names, orphaned references, and built-in print-area / filter-database names in place. Cleaning the symbol table requires explicit work.

1. Open the Name Manager and show all names

The Name Manager (Formulas → Name Manager) shows visible names. To see hidden ones, run a quick VBA snippet: For Each n In ActiveWorkbook.Names: n.Visible = True: Next. Then re-open the Name Manager and review every entry.

2. Delete orphaned and external-reference names

Filter to #REF! and to refersTo expressions containing [ or \\ or http. Delete the ones the workbook does not actually need. Test the workbook still calculates afterward.

3. Sanitize names that telegraph intent

Rename labels that describe internals: CFO_ApprovedDiscountDiscountFloor, Margin_TooLow_DoNotSenddelete entirely if not needed. The cell formulas may need to be re-pointed; that is the point.

4. Remove built-in scratch entries from sheets you no longer print or filter

For each sheet, clear the print area (Page Layout → Print Area → Clear Print Area) and turn off AutoFilter. Both actions remove the corresponding _xlnm. entries on that sheet.

5. Strip programmatically as a final pass

A short Python script can wipe every name in one pass:

from openpyxl import load_workbook

wb = load_workbook("in.xlsx")

for n in list(wb.defined_names):

del wb.defined_names[n]

wb.save("out.xlsx")

This is destructive: any formula that referred to a deleted name now resolves to #NAME?. Use it only on a copy intended as a final, locked-down deliverable, ideally one converted to values-only first.

Pre-Share Checklist

Run this checklist against any workbook leaving the organization with named ranges or formulas:

  • Have I made all hidden names visible and reviewed the entire symbol table, not just the Name Manager?
  • Are there any orphaned (#REF!) names whose label alone reveals deleted content?
  • Do any names contain external paths (\\server\, drive letters, OneDrive sync paths, URLs)?
  • Do any names point to closed external workbooks via [N] indices, and have I cross-checked _rels/workbook.xml.rels to see what file [N] actually was?
  • Are any name labels sensitive in their own right (CFO_*, Internal_*, DoNotShare_*, Layoff_*, project codenames)?
  • Have I cleared print areas on sheets the recipient will not be printing, removing _xlnm.Print_Area entries that crop to internal-only ranges?
  • Have I removed AutoFilter on hidden working sheets, eliminating _xlnm._FilterDatabase entries that point to internal data ranges?
  • Are there VBA-bound names (vbProcedure="1") whose procedure names describe sensitive code paths?
  • For final deliverables, did I consider converting to values-only first and then stripping the entire <definedNames> element programmatically?

Conclusion

The symbol table is one of the most informative metadata layers in an XLSX, and one of the least audited. The Name Manager hides as much as it shows; the underlying XML hides nothing. A reader who unzips the workbook and reads xl/workbook.xml walks away with a map of the workbook’s history — deleted sheets named in stranded entries, external workbooks identified by their full network paths, internal review labels in plain text, function-prefix fingerprints pinning down the author’s Office build, and procedure-bound names sketching out what the VBA does without parsing a byte of it.

Defined names are useful, and most workbooks benefit from a thoughtful symbol table. Treating that table as a public-facing artifact — pruning it, sanitizing labels, eliminating orphaned references, removing names that point outside the file — is what separates a workbook the recipient was meant to read from a workbook the recipient will read in ways the author never expected.

Audit the Symbol Table of Your Workbooks

Use MetaData Analyzer to enumerate every defined name in your XLSX files, including hidden, built-in, and orphaned entries. Spot external references, sensitive labels, and version-revealing function prefixes before your workbooks leave the organization.