> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dualentry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Validate and Tie Out a Migration

> Prove migrated books match the old system: trial balance by period, retained earnings roll-forward, AR and AP subledger agreement, and how to resolve breaks.

Use this guide after a migration sync completes and before you post anything new in DualEntry. You finish with a signed workpaper an auditor can follow: period-by-period trial balance agreement, a retained earnings roll-forward that ties, AR and AP subledgers that agree to their control accounts, and a documented explanation for every difference you accepted.

DualEntry does not generate a tie-out report. Tie-out is a procedure you run: the migration surfaces its own exceptions on the Error and Skipped tabs, and the steps below turn those plus your source exports into evidence.

## Before you start

Assemble these before you open a report. Gathering them afterwards is what turns a two-hour tie-out into a two-day one.

* Source exports as of the cutover date, pulled from the old system and not re-pulled later: trial balance for every migrated period, AR aging, AP aging, and a general ledger detail export. Once the source subscription lapses you cannot get them back.
* A migration whose Data Sync step shows no records left in **Ready to sync**. Records still queued will move balances after you finish.
* Read access to the [custom report builder](../reporting-analytics/custom-report-builder) and the [aging reports](../reporting-analytics/aging-reports), plus permission to open the migration at **Configuration → Company → Migrations**.
* Your account mapping spreadsheet, or the exported Accounts Mapping tab, so you can trace a DualEntry account back to its source account.
* A decision on your materiality threshold for accepted differences, agreed with whoever signs off. The rest of this guide assumes a break above that threshold gets resolved rather than explained.

## Step 1: Clear the migration's own exception tabs first

Open the migration at **Configuration → Company → Migrations** and work the Data Sync step before you run a single report. A record sitting in **Error** never reached the ledger, so a trial balance run over the top of it will be wrong in a way no comparison explains.

Check each tab and resolve it:

* **Error.** Read the message column, fix the underlying cause, and use **Retry** from the row or the bulk action bar. Errors cluster: one unmapped account usually explains a hundred failed transactions.
* **Skipped.** Confirm every skipped record was skipped deliberately. Skipping applies to every source record mapped to the same target, so one skip can remove more than you intended.
* **Ready to sync.** Sync them or skip them. Do not tie out with records in flight.

Then open the Accounts Mapping step and check its **Error**, **Skipped**, and **Deactivated** tabs the same way. An account that is deactivated in DualEntry still holds any balance already posted to it, and it will appear in your trial balance while being absent from your mapping spreadsheet.

## Step 2: Compare the trial balance period by period

Run the trial balance in DualEntry for each migrated period and compare it to the same period from the source system. Compare every period you migrated, not just the cutover date. A single as-of comparison hides offsetting errors: a transaction posted to the wrong month nets to zero at the end of the year and is still wrong.

Work from the source side, because the source is what you are proving agreement with. For each source account, find the DualEntry account it maps to and compare the closing balance. Where several source accounts map to one DualEntry account, sum the source side before comparing.

Three differences are expected rather than errors, and each has a specific cause you can confirm:

| What you see                                                                                                                                            | Where it comes from                                                                                                                                      |
| ------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A small balance in Rounding Gain/Loss with no source equivalent                                                                                         | The importer plugs constructed lines to the source document total. See [Step 4](#step-4-resolve-the-differences-you-find).                               |
| A balance in an account named `[QuickBooks] Default Expense`, `[QuickBooks] Default Income`, `[Xero] Default Income`, or `[Xero] Unpaid Expense Claims` | DualEntry creates these fallback accounts when a source line has no mappable account. Anything sitting in one is a mapping gap, not a rounding artifact. |
| Revenue and expense balances that stop at your cutover date                                                                                             | Expected when you migrated balance sheet history only. Confirm it matches the scope you chose.                                                           |

Record the comparison as a workpaper with one row per account, both balances, and the difference. The file is the deliverable.

## Step 3: Roll forward retained earnings and tie the subledgers

Two checks catch what an account-by-account comparison misses, because both test relationships rather than balances.

**Retained earnings roll-forward.** Take opening retained earnings from the source system at the start of the first migrated period, add net income per the DualEntry income statement for the migrated periods, subtract distributions and any equity movements, and compare the result to closing retained earnings in DualEntry. A break here means a transaction landed in the wrong period or the wrong account type, and it is the check most likely to surface a systematic mapping error rather than a one-off.

**AR and AP subledger agreement.** Run the [AR aging](../reporting-analytics/aging-reports#ar-aging) and [AP aging](../reporting-analytics/aging-reports#ap-aging) as of the cutover date and agree each total to its control account balance on the trial balance. Then agree both to the source system's aging by customer and by vendor, not just in total. Two customers with offsetting errors produce a correct total and a wrong subledger.

Where a journal entry deliberately touches a customer or vendor subledger without being an open receivable or payable, confirm whether it carries the **Exclude from AR aging** or **Exclude from AP aging** flag described in the [journal entries reference](../core-financials/general-ledger/journal-entries#exclude-a-journal-entry-from-ar-or-ap-aging). That flag is the usual reason an aging total and a control account legitimately differ.

## Step 4: Resolve the differences you find

Most breaks trace to one of a small number of causes. Work them in this order, because each one can produce the next.

**Unmapped or wrongly mapped accounts.** A balance in a synthetic default account, or a source account whose DualEntry counterpart is empty, is a mapping problem. Fix the mapping on the Accounts Mapping step, then retry the affected records. Fixing the mapping alone does not move transactions that already posted.

**Rounding plugs.** When constructed lines do not sum to the source document total, the importer posts the difference to Rounding Gain/Loss. It only does this within a bound: roughly $0.01 per line with a floor of $0.05 for diagnostics, and a posting ceiling of \$1.00 unless a materiality threshold is configured on the integration to widen it. A difference larger than the ceiling fails the record outright rather than posting a large plug, which is why a material break shows up on the Error tab instead of quietly in your books.

**Period placement.** Compare by period, then by document date, for any account that ties in total but not by month.

**Records you skipped.** Re-read the Skipped tab against your trial balance difference. A skipped bill is a missing AP balance and a missing expense in the same amount.

Document each accepted difference with its cause and its amount. An auditor accepts a documented, immaterial rounding plug. An auditor does not accept an unexplained difference of the same size.

## Verify

The migration is tied out when all of these hold, and when each one is saved as a workpaper rather than a screen you looked at:

* Every migrated period's trial balance agrees to the source, account by account, with differences documented and within your materiality threshold.
* The retained earnings roll-forward ties from source opening balance to DualEntry closing balance.
* AR and AP aging totals agree to their control accounts and to the source aging by counterparty.
* The Data Sync step shows no records in **Error** or **Ready to sync**, and every record in **Skipped** was skipped deliberately.
* Any balance in a synthetic default account is either zero or explained.
* The migration's **Activity** log and the DualEntry [audit trail](../platform-configuration/audit-trail-and-compliance) show who ran the sync and when, which is the evidence that the numbers came from the migration rather than from manual entry afterwards.

## Troubleshooting

Breaks in a migration tie-out come from mapping, from period placement, or from records that never landed. The table below maps the symptom to the cause.

| What you see                                                   | What to do                                                                                                                                                              |
| -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Trial balance ties in total but not by period                  | A transaction posted under a different date than the source. Compare by document date on the affected account and check the source record's date fields.                |
| An account has a balance in DualEntry and none in the source   | Two or more source accounts map to it. Sum the source side before concluding there is a break.                                                                          |
| A balance sits in a `[QuickBooks]` or `[Xero]` default account | Source lines had no mappable account. Map the real account, then retry those records. These accounts can be mapped or deactivated but never skipped.                    |
| AR aging total does not match the AR control account           | Look for journal entries flagged **Exclude from AR aging**, and for customer payments applied after your source export was pulled.                                      |
| Retained earnings is off by exactly one period's net income    | The cutover period was migrated on both sides of the boundary, or income statement history was migrated when you planned balance sheet only.                            |
| A difference equals a small number of cents per document       | Rounding plugs posted to Rounding Gain/Loss. Expected, bounded, and documentable.                                                                                       |
| Records show **Error** with a rounding or drift message        | The plug required exceeded the postable ceiling, so the record failed rather than posting. Investigate the source document; do not widen the threshold to make it pass. |
| Balances change while you are tying out                        | A scheduled re-sync ran. Confirm the sync history, then re-run the comparison against a fixed point.                                                                    |

## Related reading

* [Migration Data Scope](./migration-data-scope)
* [How to Run a Migration Cutover](./migration-cutover-runbook)
* [Migration Failure Modes and Recovery](./migration-failure-modes)
* [Migrating from QuickBooks or Xero](./from-quickbooks-xero)
* [Aging Reports](../reporting-analytics/aging-reports)
* [Journal Entries: Reference](../core-financials/general-ledger/journal-entries)
* [Audit Trail and Compliance](../platform-configuration/audit-trail-and-compliance)
