← All guides

CONCAT in Google Sheets takes exactly two arguments (Excel and LibreOffice take many)

Every one of the three engines has a CONCAT function, all three document it, and our function inventory records it as present in Excel, Google Sheets and LibreOffice Calc alike. That inventory-level agreement hides a signature difference big enough to break a workbook. Excel’s CONCAT takes up to 253 arguments and each one may be a range; Google’s CONCAT takes exactly two scalar values. Feed Sheets the Excel form and it does not concatenate fewer items, or drop the extras — it returns #N/A.

The surprise

An .xlsx full of =CONCAT(A2:A50) opens in Google Sheets with no missing-function warning at all. CONCAT is a real Sheets function, so there is no #NAME? to tell you something is unsupported. Instead every such cell reads #N/A, our executed run confirms it, and the only CONCAT call that survives the trip is the two-argument one. LibreOffice Calc, meanwhile, accepts the Excel form unchanged in every build we tested — so the workbook that migrates cleanly to Calc is the same workbook that fails in Sheets.

Executed results

Inputs, per case: =CONCAT(A1:A3) reads A1:A3 = x, y, z; =CONCAT(A1:B2) reads A1:B2 = a, b / c, d; the other two take literals.

CaseFormulaExcel (documented)Google Sheets (Drive import, 2026-08-29)LibreOffice Calc 25.8.7.3 (executed)
CONCAT_literals=CONCAT("a","b","c")abc#N/Aabc
CONCAT_range=CONCAT(A1:A3)xyz#N/Axyz
CONCAT_2d_range=CONCAT(A1:B2)abcd#N/Aabcd
CONCAT_mixed_types=CONCAT("val:",5)val:5val:5val:5

The split is exactly the two-argument line. =CONCAT("val:",5) passes two scalar values, and it is the one row where Excel’s documented result, the executed Sheets value and the executed LibreOffice value all read val:5. The three-literal call passes one argument too many; the two range calls pass a range where Sheets wants a scalar. All three return #N/A in the Sheets run and all three return the documented string in Calc.

One thing this is not: an import artifact. The Sheets CONCAT rows come from the 2026-08-29 plain-name run, in which the cells were written as literally =CONCAT("a","b","c") and =CONCAT(A1:A3) — no _xlfn. storage prefix for Google’s importer to fail to map. Sheets received the plain name it documents, resolved the function, and rejected the arguments.

LibreOffice takes the Excel form, and has for four releases

There is no version cliff here of the kind that catches VSTACK or TEXTSPLIT. We ran the same four CONCAT cases through LibreOffice Calc 24.2.0.3, 24.8.7.2, 25.2.0.3 and 25.8.7.3, and all four cases matched their documented result in all four builds — abc, xyz, abcd, val:5, with no #NAME? anywhere. Range arguments and long argument lists both work. Whatever release of Calc a reader is on within our tested range, the Excel-style CONCAT is safe there; the risk is entirely on the Sheets side.

That is the mirror image of the pattern in which LibreOffice version you need for VSTACK, TEXTSPLIT, TAKE and DROP, where the modern array functions are simply absent from older Calc builds and announce it with #NAME?. A missing function is loud. CONCAT is the quieter failure mode: the function is present in both engines and documented by both vendors, and only the shape of its argument list differs.

What the two vendors actually document

Google’s help for CONCAT lists the syntax as CONCAT(value1, value2) — “returns the concatenation of two values, equivalent to the & operator” — and states that value1 and value2 can be any scalar value or a reference to a scalar value. Two arguments, both scalars: a range is not a scalar, and there is no third slot. Google lists it in the Operator category rather than the Text category, alongside ADD and MULTIPLY. Many-argument and range concatenation in Sheets is the job of a different function: CONCATENATE, documented there as CONCATENATE(string1, [string2, ...]); TEXTJOIN, documented as TEXTJOIN(delimiter, ignore_empty, text1, [text2], …); or the Sheets-only JOIN, documented as JOIN(delimiter, value_or_array1, [value_or_array2, ...]).

Microsoft documents CONCAT(text1, [text2],…) with up to 253 text arguments, each of which may be “a string, or array of strings, such as a range of cells”, and ships it in Excel 2019 and Microsoft 365. So both descriptions are accurate for their own product; they simply describe different functions that happen to share a name. Nothing in an .xlsx records which one the author meant.

The portable alternatives, executed

CONCATENATE and TEXTJOIN are in our corpus too, and unlike CONCAT they behave the same way in both engines we execute. Inputs: A1 = Hello, B1 = World for the cell-reference case; A1 = 42 for the coercion case; A1:A3 = x, y, z for the TEXTJOIN range case; and A1:A2 = a, b with B1:B2 = c, d for the multi-range case.

FormulaExcel (documented)Google Sheets (Drive import, 2026-08-29)LibreOffice Calc 25.8.7.3 (executed)
=CONCATENATE("a","b","c")abcabcabc
=CONCATENATE(A1," ",B1)Hello WorldHello WorldHello World
=CONCATENATE("Item ",A1)Item 42Item 42Item 42
=TEXTJOIN(",",TRUE,"a","","b")a,ba,ba,b
=TEXTJOIN(",",FALSE,"a","","b")a,,ba,,ba,,b
=TEXTJOIN("-",TRUE,A1:A3)x-y-zx-y-zx-y-z
=TEXTJOIN(",",TRUE,A1:A2,B1:B2)a,b,c,da,b,c,da,b,c,d

Every row above matched its documented result in both executed engines: seven cases, no mismatches, no errors. That includes the two that do the work CONCAT could not — =TEXTJOIN("-",TRUE,A1:A3) joining a range, and =TEXTJOIN(",",TRUE,A1:A2,B1:B2) flattening two ranges in order. The ignore_empty flag also behaves identically in both: TRUE drops the empty string and FALSE keeps it as a segment, so a delimiter-doubling a,,b means the same thing on either side of a migration.

A file-format footnote worth knowing, because it is a common false alarm: in our Sheets run the TEXTJOIN cells were stored in the .xlsx under Excel’s _xlfn.TEXTJOIN name and Google’s importer mapped that form correctly, returning the documented values. So the _xlfn. prefix in a raw .xlsx is not by itself a sign of trouble — and conversely, the CONCAT failures above happened without any prefix in play.

How to migrate safely

Search for the pattern before you open the file in Sheets. Any CONCAT call with a range argument, or with three or more arguments, is a cell that will read #N/A after the import. A single =CONCAT(A1,B1) is fine and needs no change.

For a range: use TEXTJOIN with an empty delimiter. =CONCAT(A1:A3) becomes =TEXTJOIN("",TRUE,A1:A3), which joins the same three cells with nothing between them. Note the exact case in the table above is the delimited form, =TEXTJOIN("-",TRUE,A1:A3)x-y-z; the empty-delimiter variant differs only in that first argument, and we did not run it as a separate case. Use TRUE for ignore_empty if blank cells in the range should vanish, which is what CONCAT effectively does with them; use FALSE only if you are also supplying a delimiter and want the gaps preserved.

For a fixed list of values: use CONCATENATE or &. =CONCAT("a","b","c") becomes =CONCATENATE("a","b","c") or simply ="a"&"b"&"c". Both are portable; the ampersand operator is the most portable thing in this entire article, since it predates all three of these functions.

If the workbook is Sheets-first, JOIN is also available=JOIN("",A1:A3) — but it is a Google-only function: our inventory records it as documented in Sheets and not in Excel or LibreOffice, so it is a one-way door. It has no case in our executed corpus, so we are reporting Google’s documentation for it, not a measurement. TEXTJOIN is the better default precisely because it is the one that runs everywhere we tested.

Do not paper over it with IFERROR. =IFERROR(CONCAT(A1:A3),"") turns the #N/A into a blank cell, which is worse: the sheet looks healthy and silently loses the joined text. Rewrite the formula.

For the wider question of which of these three joining functions to reach for in the first place, see CONCATENATE vs CONCAT vs TEXTJOIN, and for worked examples, how to use TEXTJOIN and how to combine cells.

Honest limits

The Excel column on this page is Microsoft’s documented behaviour as recorded in our test corpus — we do not run Excel, and no value in that column is a measurement. The Google Sheets column is executed output from a single dated run: the corpus was written to .xlsx with no cached results, imported to Google Drive on 2026-08-29, recalculated by Google’s engine, and exported back for readback. Sheets has no version to pin, so that run is dated rather than versioned, and Google could change the signature of CONCAT tomorrow without changing a version number. The LibreOffice column is executed output from Calc 25.8.7.3, with the four-release claim above traced to results files from 24.2.0.3, 24.8.7.2, 25.2.0.3 and 25.8.7.3 — the only builds we ran, so we cannot speak to releases outside that range.

Two further limits specific to this page. First, our corpus has four CONCAT cases; they are enough to locate the boundary at two scalar arguments and consistent with Google’s published signature, but we did not probe every arity or argument type. Second, our readback records the error code a cell holds, not the hover message Sheets shows beside it, so #N/A above is the value we measured and the argument-count explanation comes from Google’s documentation rather than from a message we captured. JOIN has no executed case at all here. See our methodology for how recalculation is proven rather than assumed.

Check before you migrate