Searches any range and returns a value from any other, in either direction, with a built-in fallback.
XLOOKUP is the lookup function Excel should always have had. Instead of one range that has to contain both the thing you search and the thing you return, it takes them separately: here is the column to search, here is the column to return. That one change removes almost every VLOOKUP limitation at once.
It matches exactly by default, so the silent wrong-answer bug that catches VLOOKUP users cannot happen. It can return a column to the left of the one it searched. It takes a not-found value as an argument, so you rarely need IFERROR. And because you name the return range directly, inserting a column into the middle of your data does not quietly change what the formula returns.
The catch is availability: XLOOKUP exists in Microsoft 365 and Excel 2021 onwards. A workbook that has to open in Excel 2019 or earlier still needs VLOOKUP or INDEX+MATCH.
=XLOOKUP(lookup_value, lookup_array, return_array, [if_not_found], [match_mode], [search_mode])lookup_valuelookup_arrayreturn_arrayif_not_foundmatch_modesearch_modeHeaders in row 1, data in A2:D5.
| A | B | C | D | |
|---|---|---|---|---|
| 1 | Product | Category | Stock | Price |
| 2 | Cordless drill | Power tools | 24 | 89.99 |
| 3 | Extension lead | Electrical | 140 | 12.5 |
| 4 | Safety goggles | Safety | 68 | 7.25 |
| 5 | Work gloves | Safety | 210 | 5.4 |
=XLOOKUP("Safety goggles", A2:A5, D2:D5)Result: 7.25
Search column A, return the matching row of column D. No column counting, no fourth argument for exact match.
=XLOOKUP(7.25, D2:D5, A2:A5)Result: Safety goggles
The reverse lookup VLOOKUP cannot do: searching column D and returning column A, which is to its left.
=XLOOKUP("Hammer", A2:A5, D2:D5, "Not stocked")Result: Not stocked
The fourth argument handles the miss directly, so there is no #N/A and no IFERROR wrapper.
=XLOOKUP("Safety", B2:B5, A2:A5, "None", 0, -1)Result: Work gloves
Two rows match Safety. search_mode -1 searches bottom to top, so this returns the last match rather than the first.
Reading about a formula is not the same as writing one. Open this function's exercise and type it into a real grid — you get instant feedback on exactly which cell is wrong and why.
Why it happens: No match, and no if_not_found argument was supplied. The same text-versus-number and trailing-space mismatches that break VLOOKUP break XLOOKUP too.
How to fix it: Supply the fourth argument with something meaningful, and check both sides are the same data type.
Why it happens: lookup_array and return_array are different sizes — a common result of selecting one range to the bottom of the data and the other to the bottom of the sheet.
How to fix it: Make both ranges exactly the same height. Converting the data to a Table and using structured references avoids this entirely.
Why it happens: The Excel version in use does not have XLOOKUP, so the name means nothing to it.
How to fix it: XLOOKUP needs Microsoft 365 or Excel 2021+. For older versions use INDEX+MATCH, which does the same job and works everywhere.
On typical spreadsheets the difference is not noticeable. XLOOKUP scans only the two ranges you name rather than the whole table, which helps on very wide data, but you should choose it for correctness and readability rather than speed.
Their Excel is older than 2021. XLOOKUP is not available there and the file will show #NAME? wherever you used it. If the workbook has to be shared with older versions, use INDEX+MATCH instead.
It returns one match, but that match can be an entire row or column: pass a return_array several columns wide and the whole record spills into the neighbouring cells. To return every row that matches a condition rather than just one, use FILTER.
Longer reads where this function does real work in a real sheet.