FVSCHEDULE silently drops a text rate in LibreOffice, where Excel documents #VALUE!
FVSCHEDULE compounds a principal through a list of period rates: hand it 1 and the
schedule 9%, 11%, 10% and it returns 1.33089, because
1 × 1.09 × 1.11 × 1.10 is 1.33089. It is the function you reach for
when the rate changes every period — a floating-rate loan, a stepped-discount schedule, a
year-by-year inflation series read out of a column.
Microsoft is unusually explicit about what happens if that column contains something that is not a
number. From the FVSCHEDULE page, verbatim: “The values in schedule can be numbers
or blank cells; any other value produces the #VALUE! error value for FVSCHEDULE. Blank cells are taken
as zeros (no interest).” Two rules in one sentence: a blank is a 0% period, and anything else is
a hard error.
LibreOffice implements the first rule and not the second. We executed
=FVSCHEDULE(1,A1:A2) with A1 = 0.09 and A2 = "x". Calc 25.8.7.3
returned 1.09. Google Sheets returned #VALUE!, as documented.
The surprise
The error that was supposed to stop the calculation is the thing that goes missing, and what
replaces it is a plausible number. 1.09 is exactly what you get from a one-period
schedule — the text period contributed no growth at all. A schedule of twelve rates with one
bad cell in it does not fail in LibreOffice; it quietly compounds eleven periods and hands you a
future value that is too low, in a cell that looks completely normal. All four LibreOffice builds we
tested (24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3) returned 1.09.
Executed: the whole FVSCHEDULE corpus
These are all five FVSCHEDULE cases in our function corpus, run as written. The Excel
column is Microsoft’s documented behaviour and is the value both engines shown here are measured
against — we do not run desktop Excel. The Google Sheets column is executed output from the dated
Drive-import run of 2026-08-31. The LibreOffice column is Calc 25.8.7.3, and every row returned the
identical value in 24.2.0.3, 24.8.7.2 and 25.2.0.3 as well.
| Formula | Schedule | Excel, desktop (documented) | Google Sheets (executed 2026-08-31) | LibreOffice Calc 25.8.7.3 (executed) |
|---|---|---|---|---|
| =ROUND(FVSCHEDULE(1,A1:A3),7) | 0.09, 0.11, 0.1 | 1.33089 | 1.33089 | 1.33089 |
| =ROUND(FVSCHEDULE(10000,A1:A2),4) | 0.05, 0.05 | 11025 | 11025 | 11025 |
| =ROUND(FVSCHEDULE(1000,A1:A3),4) | 0.1, blank, 0.1 | 1210 | 1210 | 1210 |
| =ROUND(FVSCHEDULE(1000,A1:A2),4) | -0.1, 0.1 | 990 | 990 | 990 |
| =FVSCHEDULE(1,A1:A2) | 0.09, "x" | #VALUE! | #VALUE! | 1.09 |
Four rows out of five are perfect agreement, including the two that carry the arithmetic:
Microsoft’s own documented example and a negative rate that shrinks the principal. The
blank-cell row is worth its own sentence, because it is the rule that does hold everywhere:
1000 × 1.1 × 1.0 × 1.1 = 1210, so the empty cell in the middle of the
schedule really is a 0% period in both engines shown here, not a skipped one. That is the opposite of
how most statistical functions treat a blank, and it is documented.
What 1.09 does and does not tell us
Be precise about what the measurement proves. The executed value is 1.09, from a
principal of 1 and a schedule of 0.09 followed by "x". There are two ways to
get there:
The text was treated as a blank — that is, a 0% period.
1 × 1.09 × 1.00 = 1.09.
The text was skipped entirely, leaving a one-period schedule.
1 × 1.09 = 1.09.
Our corpus cannot separate those two readings, because on this input they produce the same number, and we are not going to assert one over the other from a single case. What we can say is the part that matters to a migration: the documented error did not occur, and the period contributed no growth. Under either reading the future value comes out as if that period had a rate of zero, so the financial consequence is identical — a compounding period silently dropped out of the calculation.
This is a rare kind of divergence
Most of the ways LibreOffice diverges from Microsoft’s documentation are error-code substitutions: the formula still fails, and only the label on the failure changes. We have executed 272 such cases, in 135 functions; they are collected in every error code LibreOffice reports as #VALUE!. Those are a real migration problem, but they are a visible one.
Cases where LibreOffice returns an ordinary value where Microsoft documents an error are much rarer. Across our whole corpus — 2,334 executed cases over 586 functions, as of 2026-09-01 — 531 cases have a documented result that is an error, and in LibreOffice Calc 25.8.7.3 38 of them come back as a value instead of any error at all. That is about 7% of the error-expected set, against 51% for the error-code substitutions.
Most of the 38 are one recognisable shape, and it is not the shape this page is about: a
statistical distribution evaluated outside its documented domain returning a boundary value rather
than #NUM! (LOGNORM.DIST, LOGNORMDIST,
EXPON.DIST, EXPONDIST, GAMMADIST, CHIDIST,
BETADIST, BETA.INV, BETAINV, BINOM.INV,
CRITBINOM, NEGBINOMDIST, PERMUT, PERMUTATIONA), or
a trigonometric function accepting an argument past the documented magnitude ceiling
(COT, COTH, CSC, CSCH, SEC,
SECH). Those are inputs a working model rarely reaches, and when it does the answer is
usually 0 or 1 and looks like what it is.
Four of the 38 return money. That is the group this page belongs to, and it has grown since this page was first written:
| Formula | Excel, desktop (documented) | Google Sheets (executed 2026-08-31) | LibreOffice Calc 25.8.7.3 (executed) | What the silent value is |
|---|---|---|---|---|
| =FVSCHEDULE(1,A1:A2) with A2 = "x" | #VALUE! | #VALUE! | 1.09 | a future value with one compounding period missing |
| =AMORDEGRC(A2,A3,A4,A5,A6,0.22,A8) | #NUM! | #NAME? | 696 | a depreciation amount for a documented-invalid life |
| =AMORDEGRC(A2,A3,A4,A5,A6,0.4,A8) | #NUM! | #NAME? | 820 | the same, at a different rate |
| =TBILLPRICE(A2,A2+400,A4) | #NUM! | #NUM! | 90.1 | a price for a bill maturing more than a year out |
All four of those returned the same value on 24.2.0.3, 24.8.7.2 and 25.2.0.3 as well. Across the
full set of 38, all four builds return a value rather than the documented error every time, and on 37
of the 38 that value is identical across the builds; the one exception is
=FORECAST.ETS.CONFINT(21,C1:C20,E1:E20) over a duplicate timeline, where the four builds
return four different numbers (3.94384389, 3.80076060, 4.08717124 and 3.66439998) in place of the
documented #VALUE!.
The AMORDEGRC and TBILLPRICE rows are written up with the rest of the
fixed-income family in
bond
and treasury functions after a migration; TBILLPRICE in particular is worse than it
looks, because the price it invents does not follow the documented formula on any day count. Google
has no AMORDEGRC, so those two rows say nothing about Sheets either way.
The four cases with their own write-ups on this site are the ones where the silent value is not money, and they are the useful contrast:
| Formula | Excel, desktop (documented) | LibreOffice Calc 25.8.7.3 (executed) | Written up in |
|---|---|---|---|
| =MROUND(5,-2) | #NUM! | 6 | MROUND with a negative multiple |
| =POWER(-8,1/3) | #NUM! | -2 | POWER with a negative base |
| =CHAR(0) | #VALUE! | the escape string _x0000_ | CHAR and UNICHAR of zero |
| =UNICHAR(0) | #VALUE! | the escape string _x0000_ | CHAR and UNICHAR of zero |
MROUND(5,-2) = 6 and POWER(-8,1/3) = -2 are at least arguable answers to
a question the documentation calls invalid — and Google Sheets returns -2 for the
POWER row too, so LibreOffice is not alone on that one. _x0000_ is visibly
wrong the moment you look at the cell. A future value that is 9% too low after one dropped period is
none of those things: it is the right shape, the right magnitude and the wrong number, which is the
only combination that survives a review.
A migration checklist for rate schedules
1. Find every FVSCHEDULE and look at the range, not the formula. The
formula is fine. The hazard is entirely in what the schedule range contains on the day it runs.
Search the workbook for FVSCHEDULE( and note the second argument of each hit.
2. Assume the schedule column has text in it until you have checked. The
usual sources, in rough order of how often they turn up: a placeholder like n/a,
TBD, — or ? left in a future period; a header row or
label caught inside the range when someone extended it; a rate pasted from a PDF or a web page and
stored as text; an apostrophe-prefixed cell. Any of these produces #VALUE! in Excel and
Google Sheets, and a quiet under-compounding in LibreOffice.
3. Count the periods that actually compounded. The cheapest independent check is a
second cell that does not use FVSCHEDULE at all:
=SUMPRODUCT(--ISNUMBER(schedule)) against =ROWS(schedule). If those two
disagree, some period in your schedule is contributing nothing, whatever the future-value cell says.
This is arithmetic we are describing rather than a case we executed — treat it as a suggested
guard, not as a measured result.
4. Guard the input rather than the output. Wrapping the call in
IFERROR is exactly the wrong move here: in Excel and Sheets it swallows the
#VALUE! that was warning you, and in LibreOffice there is no error to catch in the first
place, so it changes nothing. If you want the workbook to behave the same in all three, test the
schedule explicitly — something in the shape of
=IF(SUMPRODUCT(--ISNUMBER(schedule))<>ROWS(schedule),NA(),FVSCHEDULE(p,schedule))
— so the failure is yours and not the engine’s. Again: a suggestion derived from the
documented and executed behaviour above, not a formula we ran.
5. Watch the direction of travel. A workbook authored and sanity-checked in
LibreOffice can carry a text cell in a schedule for years without anyone noticing, because it never
complains. Open that same file in Excel or Google Sheets and the cell turns into #VALUE!,
which then propagates into every total that touches it. The migration does not create the bug; it
reveals one that was already producing wrong numbers.
Honest limits
The Excel column is Microsoft’s documented behaviour as recorded in our test corpus, quoted
from the FVSCHEDULE page. We do not run desktop Excel, and no value in that column is a
measurement.
The Google Sheets column is executed output from a dated run, because Sheets has no version number
to pin. A formula-only .xlsx carrying no cached results goes to Google Drive, is recalculated by
Google’s engine, and comes back as .xlsx for readback, with a deterministic
=1111+2222 canary in every sheet proving the recalculation happened. These five cases ran
on 2026-08-31.
The LibreOffice column is executed output from Calc 25.8.7.3; the same five cases returned the same five values in 24.2.0.3, 24.8.7.2 and 25.2.0.3. Those four builds are the only ones we tested.
Scope. Our text probe is the literal string "x" in a two-cell schedule. We have no
corpus case for a numeric string such as a rate stored as text, for an error value inside a
schedule, for a logical value inside a schedule, or for a schedule passed as an array constant rather
than a range — so we make no claim about any of those, and a workbook whose real-world hazard is
“numbers stored as text” should be checked directly rather than assumed to match the
"x" result. See our methodology for how recalculation is
proven rather than assumed, and the FVSCHEDULE function
page for the per-engine support matrix.
Check before you migrate
A note on which Excel this is. The Excel column in the tables above is Microsoft’s documented behaviour for desktop Excel, as recorded in our test corpus — we do not run desktop Excel, and no value in that column is a measurement. Excel for the web is a different application with its own calculation engine, and that one we do run (recalculated on OneDrive, 2026-09-01). Its measured results are published on each function’s own page rather than in these guide tables. Because we have no desktop run to compare against, a disagreement between an Excel-web measurement and the documented column is genuinely ambiguous: it may mean the web engine diverges from the desktop one, or that the documentation is wrong about both. We do not claim to know which.