Major Accounting Inconsistencies

We seek help understanding the root cause of unexpected General Ledger (GL) and Payment Ledger Entry (PLE) behaviour. We have reconciled and corrected most identified cases in one company, but have not proven why they arose or whether the common factor is standard ERPNext, custom code, deployment history, or a combination.
Column 1

Column 2 Column 3 Column 4
Environment ERPNext v16 / Frappe v16, MariaDB, Docker on OVH; multiple companies/sites; several custom apps. Custom apps do not post any transaction. They are majorly reporting tools
Main symptoms Repeated GL postings for one submitted invoice; active GL/PLE against Draft vouchers; cancelled vouchers retaining active ledger effects; contradictory document status.
Company A scope 293 classified exceptions: 268 duplicate-GL cases plus 25 other cases (reconciled Production audit).
Correction evidence 268 duplicates corrected through native Repost Accounting Ledger; 19 additional cases corrected; two cancelled-invoice PLE cases corrected.
Last reported state 289/293 corrected in Production; three further methods passed UAT and were authorised for Production, but their Production result is not in the available evidence; one status-conflict invoice remains blocked.

1 What users experienced
Invoices were shown as Submitted or Draft, but the ledgers did not always reflect that state. Some submitted invoices had two to four sets of accounting entries even though the PLE or customer outstanding reflected only one invoice. Other Draft transactions had posted GL entries. Some cancelled documents retained open PLE or active GL rows. As a result, GL, receivables/payables and source documents could disagree.

This is an interesting case, especially the duplicate GL entries where the Payment Ledger and outstanding amount still look correct.

Since Repost Accounting Ledger fixed most of the duplicates, I’d be curious whether you found anything common in the original entries, like creation timestamps, background jobs, or a particular upgrade or migration.

Also, do the Draft vouchers with active GL entries have the same pattern as the duplicate cases, or do they appear to be unrelated?

I wouldn’t rule out standard ERPNext or custom code yet. Even a custom app that doesn’t directly post accounting transactions could potentially affect the document lifecycle.

Have you been able to reproduce any of these issues in a clean v16 environment? That might be the best way to narrow down where they’re coming from.

Hi there,

It’s really hard to answer this without more context about your process. It should not be the case that draft Invoices have GL Entries, nor that any document is producing duplicate entries.

You mention custom code. What does it do? Were all of your invoices entered manually via the ui, or did you use apis or other methods?

I have created a complete document which list down the process which we followed and errors which we encountered. As attaching pdf is restricted, i am sharing onedrive link to download the same ERPNext_Accounting_Integrity_Community_Report.pdf

As a next step, i am removing all custom apps and its dependencies from the database and use it with vanilla ERP implementation to see if the errors persist or not.

The custom application which we build is used for preparing reports such as sales analysis, gross profit calculation,AR ageing etc. One screenshot of the custom app attached for reference. I doubt if it is caused by custom app as this custom app is for data analysis

No API is used. At max we used standard data import functionality. We could not identify the exact root cause of the issue. Majority of errors were duplicate GL posting against the same invoice/CN. In few instances, the invoice was settled against a payment but it was still reflecting in AR ageing.

I am a bit shaken after identifying these errors as we now can’t rely on the data and i was actually not expecting such fundamental issues with the ERP next. Below is the summary of what we found, tested.

ERPNext v16 — Serious Accounting Integrity Issues: Investigation, Tests, Findings and Open Questions

Purpose: Seeking technical opinions from the Frappe/ERPNext community regarding repeated GL postings, accounting entries against Draft documents, and incomplete accounting cancellation.

Investigation: 9–11 November 2026, including historical transaction analysis.

Environment:

  • ERPNext v16, Frappe Framework v16

  • MariaDB, Docker-based OVH hosting

  • India Compliance and several custom applications, including Smart Importer

  • Multiple independent Production sites

  • Accounting operations involving Sales Invoices, Purchase Invoices, Journal Entries, Payment Entries, GST and inventory

Versions reported during the final investigation included ERPNext 16.54.0 and Frappe 16.55.2. Historical transactions may have been created under earlier versions.

1. Problems we encountered

We discovered four major accounting inconsistencies.

Problem Expected ERPNext behaviour Actual behaviour observed
Duplicate General Ledger entries One valid accounting effect per submitted transaction Some submitted invoices had GL postings repeated 2–4 times
Draft transactions posting GL Draft documents should not have active accounting postings Some Draft Sales Invoices, Journal Entries and Payment Entries had active GL and/or PLE
Cancelled transactions retaining accounting entries Cancellation should complete the appropriate GL/PLE lifecycle Some Cancelled documents retained active GL or outstanding PLE
Contradictory document status Document status and accounting state should be consistent One invoice had docstatus=1, displayed Cancelled, no active GL, but open PLE

These problems caused General Ledger balances to disagree with Payment Ledger balances and the native Accounts Receivable reports.

Example: An invoice for ₹549 had two identical GL postings, causing the Debtors GL to reflect ₹1,098 while the Payment Ledger correctly reflected ₹549.

We initially suspected a recent Smart Importer upgrade. Subsequent historical investigation showed that some accounting anomalies existed much earlier.

2. Investigation steps performed

Step 1 — Compared GL with source documents

We inspected the actual database records for affected vouchers, rather than relying only on ERPNext’s General Ledger report.

For each voucher, we examined:

  • Document status (docstatus)

  • Active and cancelled GL entries

  • Debit/credit amounts by account

  • Payment Ledger entries

  • Original invoice amount and outstanding balance

  • GL creation timestamps and modification history

  • Linked payment allocations

  • Stock Ledger and IRN records where applicable

Finding: Several invoices contained multiple complete active accounting posting sets, while the corresponding source document and PLE reflected only one transaction.

This established that the problem was not merely duplicate display rows in a report.

Step 2 — Examined document Version history

We compared the Frappe Version records with actual GL creation events.

Finding: Some affected documents had multiple recorded transitions from Draft (docstatus=0) to Submitted (docstatus=1).

This was consistent with the submission lifecycle having executed multiple times.

In other cases, the document was currently Draft despite having GL entries and evidence of an earlier submission.

Unresolved question: We could not conclusively identify what returned those documents to Draft. Direct database modification or application code bypassing the normal document lifecycle remains a hypothesis, not a confirmed cause.

Step 3 — Investigated cancelled invoices appearing in Accounts Receivable

For two cancelled Sales Invoices, totalling ₹1,49,117:

  • The source invoices were Cancelled.

  • Their GL cancellation was already complete.

  • Original PLE records remained active with delinked=0.

  • No proper PLE cancellation effect had been completed.

The ERPNext Accounts Receivable report reads qualifying Payment Ledger entries. Consequently, the invoices continued to appear as outstanding even though their GL cancellation had already occurred.

Confirmed immediate cause: Incomplete Payment Ledger cancellation state.

Historical trigger: Still unknown.

Step 4 — Investigated Draft transactions with active accounting

We found Draft Sales Invoices, Journal Entries and Payment Entries with active accounting effects.

Some had both GL and PLE anomalies.

We verified their current document status, original accounting records and related transactions.

Finding: These were genuine stored accounting entries, not just reporting errors.

However, we did not establish a single historical code path responsible for creating them.

Step 5 — Expanded the investigation across Production sites

We checked historical exceptions in other companies.

Representative confirmed cases included:

Transaction Historical period Finding
Cancelled Sales Invoice 2025 Active GL rows remained after cancellation
Cancelled Purchase Invoice 2025 Active GL rows remained after cancellation
Cancelled Journal Entry 2025 Active GL rows remained after cancellation
Sales Invoices September 2026 Debtors GL reflected four times the correct document amount
Draft Sales Invoices October–November 2026 Active GL existed against Draft documents

One historical invoice had a posting date of 22 March 2025, GL created on 15 April 2025, and cancellation recorded on 12 July 2025. The incorrect cancelled-active-GL state is established after cancellation, not necessarily from the original posting date.

Important conclusion: Certain accounting integrity problems predate the earliest retained Smart Importer batch of July 2026.

This weakens the hypothesis that the recent Smart Importer upgrade caused all the anomalies.

It does not rule out Smart Importer or other custom code contributing to the later duplicate-submission incidents.

3. Tests performed on UAT

We restored Production-derived data into UAT and tested native ERPNext correction methods.

Our principal test cases were:

Test Scenario Result
1 Ordinary Sales Invoice with duplicate GL PASS
2 Duplicate GL on invoice with allocated payment PASS — allocation preserved
3 Duplicate GL generated within the same second PASS
4 Invoice with three posting waves PASS — reduced to one correct posting
5 Journal Entry with duplicate GL PASS
6 Invoice with IRN and stock transactions PASS — IRN and Stock Ledger preserved

Method A — Repost Accounting Ledger

We used ERPNext’s native Repost Accounting Ledger functionality for eligible Submitted transactions.

The option Delete Cancelled Ledger Entries remained unchecked.

Results:

  • Duplicate active GL effects were eliminated.

  • Correct source-document accounting was regenerated.

  • Payment Ledger and outstanding balances remained correct.

  • Historical cancelled entries were preserved.

  • GST, stock and IRN checks passed for the applicable test cases.

Method B — Orphan GL reversal

For Draft documents containing invalid active GL, we tested targeted reversal of the registered orphan GL entries using ERPNext accounting functions.

We verified that the Draft documents remained Draft and their invalid GL/PLE effects were eliminated.

This method was not used indiscriminately for Submitted invoices.

Method C — Payment Ledger cancellation

For cancelled invoices with active PLE, we tested the native create_payment_ledger_entry(..., cancel=1) cancellation lifecycle against verified original posting information.

Result:

  • Original PLE history was preserved.

  • Appropriate cancellation PLE history was created.

  • Incorrect outstanding amounts disappeared from AR.

  • No additional GL cancellation was performed.

The method passed UAT and subsequent Production verification for the two affected invoices.

4. Two verification problems discovered during correction

We also identified defects in our external correction-monitoring procedure.

Problem A — Repost completion race

The monitoring script treated a child repost item marked Reposted as final, although the parent Repost Accounting Ledger was still In Progress.

The parent completed shortly afterward, and the accounting was correct.

Correction: Wait for the parent RAL document to reach Completed. Never automatically retry a repost merely because monitoring timed out.

Problem B — Incorrect duplicate-wave detection

Our initial verification grouped GL entries by their creation second.

One valid repost generated GL entries across two consecutive seconds, causing a false failure.

Correction: Compare the entire active GL account-wise against the correct source-document accounting, including party, dimensions and currency, rather than using creation-second buckets.

Both issues were in our monitoring logic. Neither demonstrated a defect in ERPNext’s native reposting function.

5. Production correction results

After UAT testing, we executed controlled, sequential Production corrections.

The company was placed in maintenance mode, recovery checkpoints were retained, and GL/PLE reconciliation was performed after corrections.

Correction category Cases corrected Result
Duplicate GL postings 268 PASS
Draft/orphan accounting exceptions 19 PASS
Cancelled invoices with incorrect open PLE 2 PASS
Final invoice, Journal Entry and Payment Entry corrections 3 PASS
Total 292 PASS

Financial results

  • Duplicate GL corrections removed ₹9,34,067.66 of excess debits and ₹9,34,067.66 of excess credits.

  • The Draft/orphan accounting cleanup removed a further ₹73,519.71 on each side.

  • Two cancelled-invoice PLE corrections cleared ₹1,49,117 of incorrect AR outstanding, without an additional net GL adjustment.

  • The final three corrections passed their account-wise GL/PLE checks.

These figures represent different correction categories and should not be added together as a single profit or balance-sheet adjustment.

At the latest verified checkpoint:

  • 292 of 293 identified exceptions were resolved.

  • Accounts Payable GL and PLE reconciled.

  • Accounts Receivable GL and PLE differed by ₹2,064.

  • That remaining difference related to one documented invoice with contradictory submission/cancellation status.

  • Production remained frozen pending migration decisions.

The final ₹2,064 case was deliberately deferred rather than corrected through an unsupported status change or balancing Journal Entry.

6. What is established versus what remains unknown

Established findings

  1. Actual duplicate active GL postings existed in the database.

  2. Some Draft documents had active GL/PLE.

  3. Some cancelled documents retained inconsistent accounting records.

  4. Repeated Draft-to-Submitted transitions appeared in the history of certain affected documents.

  5. Historical cancelled-active-GL anomalies existed before the retained Smart Importer batch history.

  6. Native ERPNext accounting recovery methods successfully corrected the tested voucher patterns.

Not yet established

  1. Whether the repeated submissions originated in ERPNext core, custom applications, background workers, API calls or another process.

  2. What mechanism caused previously Submitted documents to return to Draft without a corresponding normal lifecycle record.

  3. Why some cancellation processes completed GL cancellation but left PLE cancellation incomplete.

  4. Whether historical errors across different companies share one root cause.

  5. Whether the same problem can be reproduced on unmodified ERPNext without custom applications.

A successful correction does not, by itself, establish what caused the original defect.

7. Our next diagnostic experiment

We are preparing to migrate the corrected database to Frappe Cloud and operate real business transactions for approximately three weeks.

The proposed environment will use:

  • Standard Frappe Framework v16

  • Standard ERPNext v16

  • India Compliance for Indian statutory functionality

  • No Smart Importer or other unnecessary custom applications

We intend to monitor real daily Sales, Purchase, Payment, Journal Entry, inventory and GST transactions.

The objective is to determine whether accounting integrity failures recur in a managed environment without our custom applications.

This experiment has not yet been completed. Its outcome should not be treated as evidence at this stage.

8. Questions for the ERPNext community and maintainers

We would appreciate technical guidance on the following:

  1. Repeated submissions: Under what conditions could ERPNext execute the accounting submission lifecycle more than once for the same voucher, leaving multiple complete active GL postings?

  2. Draft documents with GL: Can any supported ERPNext process legitimately leave active GL or PLE against a docstatus=0 document? If not, which application hooks, database operations or background-job paths should be investigated first?

  3. Cancellation consistency: What failure scenarios could allow GL cancellation to complete while the Payment Ledger remains active and undelinked?

  4. Transaction atomicity: Are GL, PLE and document-status updates guaranteed to roll back together when submission or cancellation fails, and are there known exceptions involving background jobs or custom hooks?

  5. Preventive controls: What is the recommended standard mechanism to prevent duplicate active accounting effects, especially during repeated API submissions, job retries or simultaneous requests?

  6. Reproduction and escalation: Which debug logs, database evidence, call stacks and version details would maintainers need to reproduce these issues and establish whether they originate in ERPNext core?

We are not seeking to attribute the problem to ERPNext without evidence. We want to identify the actual failure mechanism and implement a reliable preventive control rather than repeatedly correcting historical transactions.

We can provide sanitised voucher-level GL/PLE histories, document Version histories, before-and-after reconciliations, UAT test evidence and correction logs to maintainers for further investigation.

I did some testing on a separate ERPNext v16 environment and found something interesting with the cancellation process.

It looks like PLE cancellation depends on the GL entries available during the reversal. If those entries are already cancelled or the references don’t match, the PLE may remain outstanding.

I was able to reproduce that situation after deliberately creating an inconsistent ledger state, but not through normal invoice submission or cancellation.

It doesn’t explain what originally caused your issue, but it might be worth checking whether those affected invoices already had inconsistent GL entries before cancellation.

Hi @hrishisinhasane and welcome to the community

I see in your PDF file a mention of CSV.

Are these imports of invoices and payment entries?

Regards

Hi, the csv was list of transactions which had errors

Hi, the csv was list of transactions which had errors