Under perpetual inventory, ERPNext promises one thing: the value in your Stock Ledger always equals the balance in your Stock-in-Hand account, because every stock movement posts a matching General Ledger entry. When that promise breaks — the Stock Balance report says one number and the GL says another — it is never random. It is a stray Journal Entry, a repost that hasn't finished, backdated entries into a closed period, or a warehouse mapped to the wrong account. This guide quantifies your gap and traces it to the exact cause.
Not sure a gap even exists yet?
The two numbers to compare are the total on the Stock Balance report and the balance of your Stock-in-Hand account in the General Ledger. If they match, perpetual inventory is healthy. If they don't, the calculator below tells you whether the difference is rounding or something to chase.
A Stock Ledger that disagrees with the General Ledger is the fault that quietly erodes trust in an ERPNext deployment — because if stock value is wrong, so is COGS, and so is gross margin. I am Manoj, ERPNext and Frappe implementation lead at Mith Tech in Bengaluru; closing this gap is one of the most common accounting jobs we do on inherited instances.
How perpetual inventory is supposed to behave
With perpetual inventory enabled, ERPNext posts a General Ledger entry after every stock transaction — a receipt debits Stock-in-Hand, a delivery credits it and debits COGS, and so on. The official documentation states the invariant plainly: the value as per the Stock Ledger should always equal the relevant account balance. So the Stock Balance report total and the Stock-in-Hand account in the GL are two views of the same number.
When they disagree, something posted to one side without the other. That is the whole diagnosis, and it narrows to a short list of causes.
First, quantify the gap
Before chasing anything, measure it. A ₹20 difference on ₹25 lakh of stock is rounding; a ₹2 lakh difference is a broken entry. Put your two totals in and get a banded read.
Enter your Stock Ledger value and Stock-in-Hand GL balance to see the gap, its percentage of stock value, and whether it's rounding or a real break.
A real but small gap. Check for a stuck repost or a stray Journal Entry to a stock account before it grows.
A small moving-average gap can be genuine rounding
Under moving-average valuation, the Stock Ledger outgoing value and the GL credit can differ by rounding on individual movements — a ledger figure of 516.66 against a GL post of 500.00 on one transaction, for instance. Tiny, stable per-transaction differences are usually immaterial. A gap that grows over time is not rounding; it's one of the causes below.
Then, trace it to the cause
The Stock-vs-GL gap has a short list of causes, and they have very different fixes. Pick the one that fits what you know happened.
Select the most likely reason your Stock Ledger and General Ledger disagree to get its cause and the specific fix.
Pick the most likely reason your two balances disagree.
The manual Journal Entry — the usual suspect
Most Stock-vs-GL breaks trace to one action: someone posted a Journal Entry straight to the Stock-in-Hand account — to "adjust" a balance, to book a write-off, or to correct something they didn't understand. Perpetual inventory keeps the account tied to the ledger by only ever posting from stock transactions. A manual JE moves the accounting side alone, and the two never realign on their own. The fix is to reverse the JE and make the adjustment through a Stock Entry or Stock Reconciliation instead, so both sides move together.
The pending repost — a temporary, legitimate gap
If a backdated transaction queued a Repost Item Valuation that hasn't finished, the Stock Ledger values are mid-recalculation while the GL still shows the old numbers. This disagreement is expected until the repost completes — so before treating a gap as a break, confirm no repost is Queued, In Progress, or Failed. If one is stuck, clear it first; our Repost Item Valuation guide covers exactly that.
Backdated entries and closed periods
Stock posted into a period whose accounts were already closed leaves the ledger and the GL out of step for that window, because the recomputation may be skipped for the closed period — the pattern reported in discuss.frappe.io #134791. Where a closed period is involved, correct with a Journal Entry in the current period rather than reopening the year.
Wrong warehouse-to-account mapping
If a warehouse is mapped to the wrong account — or several warehouses share one Stock-in-Hand account that also holds unrelated balances — the account total won't line up with any single warehouse's ledger (#15148). Give stock warehouses their own accounts and compare like-for-like.
Close it, then keep it closed
Quantify the mismatch with the variance report, realign via reposting, and prevent the drift from recurring.
Find exactly which entries differ before you touch anything.
Report: Stock Ledger Variance
(Stock > Reports > Stock Ledger Variance)
It lists Stock Ledger Entries whose stock value doesn't
match the linked GL Entry — your shortlist of culprits.
Cross-check against:
• Stock Balance report (stock-side total)
• General Ledger for the Stock-in-Hand account (GL side)
The difference between those two totals is what you're closing.Run the Stock Ledger Variance report
Stock > Reports > Stock Ledger Variance. It lists the Stock Ledger Entries whose stock value doesn't match their linked GL entry — your shortlist, instead of a mystery total.
Rule out a pending repost
Check Repost Item Valuation for anything not Completed. If a repost is running or stuck, the gap may resolve itself once it finishes — clear stuck ones first and let the queue drain.
Find and reverse improper journal entries
Pull the General Ledger for the Stock-in-Hand account and look for Journal Entries — anything not originating from a stock transaction is suspect. Reverse them and re-do the adjustment through a Stock Entry or Stock Reconciliation.
Fix mappings and re-verify
Confirm each warehouse's account mapping is correct and unique where it should be. Then re-compare the Stock Balance total against the Stock-in-Hand GL balance — they should now agree within rounding.
Fix now, or monitor?
FAQ
+Why doesn't my ERPNext Stock Ledger match the General Ledger?
Under perpetual inventory the two should always agree, so a difference means something posted to one side without the other. The usual causes are a manual Journal Entry to a stock account, a valuation repost that hasn't finished, backdated entries into a closed period, or a wrong warehouse-to-account mapping. Run the Stock Ledger Variance report to find the specific entries.
+How do I fix a Stock-in-Hand account that doesn't match my stock value?
Quantify the gap, then run the Stock Ledger Variance report to list the mismatched entries. Rule out a pending repost, reverse any Journal Entry posted directly to the stock account, and correct warehouse-account mappings. Re-do adjustments through Stock Entry or Stock Reconciliation so both sides move together.
+Can I post a Journal Entry to fix a stock account balance?
No — that's usually what caused the mismatch in the first place. A Journal Entry moves the General Ledger without a matching Stock Ledger movement, so the two permanently diverge. Adjust stock value through a Stock Reconciliation or Stock Entry, which post to both sides together.
+Is a small difference between stock ledger and GL normal?
A tiny, stable difference under moving-average valuation can be genuine rounding on individual movements and is usually immaterial. A difference that grows over time is not rounding — it points to a manual journal entry, backdated entries, or a stuck repost, and should be traced.
+Does reposting fix a stock ledger vs GL mismatch?
It fixes the portion caused by backdated entries — once every Repost Item Valuation is Completed, the stock-side values realign for open periods. It will not fix a mismatch caused by a manual Journal Entry or a wrong account mapping; those need reversing and correcting directly.
+Which report shows me the mismatched entries?
The Stock Ledger Variance report (Stock > Reports) lists Stock Ledger Entries whose stock value doesn't match their linked General Ledger entry. Combined with the Stock Balance total and the Stock-in-Hand account balance in the GL, it turns a mystery total into a specific shortlist.
+Does this apply to ERPNext v14, v15 and v16?
Yes. Perpetual inventory's post-to-GL-on-every-movement behaviour, and the Stock-vs-GL causes, are the same across v14, v15 and v16 — the discrepancy reports span these versions. Report names and a few UI paths differ slightly by release.
Closing
Perpetual inventory only works if you respect its one rule: stock value changes through stock documents, never through direct journal entries to stock accounts. When the Stock Ledger and the General Ledger drift apart, quantify the gap, shortlist it with the variance report, and trace it to the stray entry or the pending repost behind it. Fix the cause, hold the rule, and the two numbers stay married — which is the only state in which your COGS and margins mean anything.
Stock value and books drifting apart and month-end is a fight?
We reconcile your Stock Ledger to the General Ledger, trace every stray entry, fix warehouse-account mappings, and set the posting rules that keep perpetual inventory honest.