Dual-Write Between Dynamics 365 (Dataverse) and Finance and Operations: Setup, Master Data, and Troubleshooting
A quick terminology note before starting: "Dynamics 365 CRM" is the old name. The apps that matter here — Sales, Customer Service, Field Service, Project Operations — run on Microsoft Dataverse, and that's the term you'll see throughout the official documentation and in this guide. On the other side sits Finance and Operations (F&O) — Finance, Supply Chain Management, Commerce, Human Resources.
Dual-write is Microsoft's bidirectional, near-real-time sync layer between the two. A change on either side triggers a write on the other, generally within seconds. It's different from the older Data Integrator / dual-write's batch cousin, which moves data on a schedule — dual-write is transactional and event-driven.
In this guide
Prerequisites
Environment versions
- Finance and operations apps: build
10.0.9 (10.0.383.20013)with platform update 33 or later - Customer engagement apps: platform version
9.1.0000.11732or later
Minimums — always confirm against the current requirements page for your release, since both sides ship on continuous update cycles.
Tenancy and region
- Both environments must sit in the same Microsoft Entra tenant — no cross-tenant setups
- Both must be deployed in the same Azure datacenter/region
- Available in a defined set of regions (Asia, Australia, Brazil, Canada, Europe, France, Germany, India, Japan, South America, Switzerland, UAE, UK, US) — no publicly announced plans to expand further
Licensing and access
- Valid Dynamics 365 licenses covering whichever CE and F&O apps you're connecting
- System Administrator in both environments to perform the link
- Only the user who originally set up the link can add new table maps afterward — plan who that account is before you start
| Limitation | Detail |
|---|---|
| Topology | Strictly 1:1 — one F&O environment to one Dataverse environment |
| Trial instances | Not supported |
| Prospect-to-Cash (Data Integrator) | Cannot run alongside dual-write; must be uninstalled first |
| Initial sync | Capped at 40 legal entities |
| Live sync | Capped at 250 legal entities |
| Cross-company data sharing | Not supported |
| Trigger events | Only fires on Insert/Update/Delete events — not on doInsert/doUpdate/doDelete |
| Distributed transactions | Not supported (a canceled posting process can leave the two sides out of sync in edge cases) |
Documentation is inconsistent here
The system-requirements page states dual-write isn't supported on cloud-hosted environments (CHE), while a separate prerequisites page carves out an exception for one required application ID specifically for customer-managed CHEs, and a troubleshooting article walks through permissions for a "one-box" cloud-hosted dev environment. If you're on a CHE, treat this as environment-specific and verify directly against current Microsoft Learn content.
Before you touch a production environment
Linking an F&O environment to a Dataverse instance is described by Microsoft as not reversible — disconnecting the two after the fact results in data loss. Rehearse the full setup on a sandbox first.
Architecture at a Glance
The two sides
Finance and Operations
Finance · Supply Chain Management · Commerce · Human Resources
near real-time
Microsoft Dataverse
Sales · Customer Service · Field Service · Project Operations
Solutions
Dual-write ships as Marketplace solutions installed into Dataverse: Application Core, Finance, Supply Chain, Human Resources, Notes, Asset Management, and a Party/Global Address Book package. Install only what your scenario needs.
Table maps
Also called entity maps — define the field-level mapping between one F&O table and one Dataverse table. The Customers V3 map, for example, ties F&O CustomerAccount to Dataverse accountnumber.
Legal entities
Each F&O legal entity is represented in Dataverse as a Company record tied to a Business Unit.
Authentication
Runs through two fixed Microsoft Entra application IDs — not something you generate yourself for the core connection. More below.
Step-by-Step Initial Configuration
The ten stages, at a glance
Confirm prerequisites
Work through the requirements above; the health check (stage 5 below) will re-verify most of it anyway, but fixing gaps beforehand saves a failed wizard run.
Link the F&O environment to a Dataverse environment
Two entry points do the same thing:
- Lifecycle Services (LCS): open the environment's Details page → expand Power Platform Integration → select Dual-write application.
- From inside F&O: go to Workspaces > Data management, select the Dual Write tile, then New link to environment to open the Setup link to Dataverse wizard.
If you don't have a Dataverse environment yet, the same flow provisions a new one. If attaching to one that already exists, you'll pick it from a list of environments where you're an admin.
Walk the linking wizard
Runs in this order: choose the Dataverse environment → select which legal entities to include → an automatic health check runs against the prerequisites → summary/confirmation. If the health check fails here, fix the reported items and re-run the wizard rather than forcing it through.
Grant the two systems access to each other
On a clean run through the wizard, this is handled for you automatically. The manual version (two Entra application rows in F&O, matching application users in Dataverse) only needs attention if the automated link fails or you're rebuilding a broken connection — see the dedicated section below.
Apply the dual-write solutions
During the wizard, select Apply Solution — this pushes the Dataverse solution packages you need. You can also install packages directly from Power Apps > Solutions > Open Marketplace if doing this outside the wizard.
Uninstall Prospect-to-Cash
If your environment has it. It cannot coexist with dual-write.
Enable table maps
Back in Data management > Dual Write, pick a map (Customers V3 is a common starting point), and select Run. A dialog lists dependent tables the map relies on — use Show related table map(s) and enable those together rather than one at a time; skipping dependencies is the single most common cause of first-run errors.
Watch the status
Each map moves through Not running → Initializing → Running. Initializing is where pre-existing data gets copied across; check the Initial sync details tab if a map sits in that state for longer than expected or drops back to Not running.
Validate with a real record
Create or update a record on one side (a test customer is usually easiest) and confirm it lands on the other side within a minute or two.
A Few Core Master Data Maps
| Map | Syncs | Key mapping | Notes |
|---|---|---|---|
| Customers V3 | Customer master (Accounts/Contacts) | CustomerAccount ↔ accountnumber | Depends on Customer groups and Currencies; enable those first |
Vendors V2 msdyn_vendors | Vendor master | Vendor-specific key mapping | Two design options exist — a dedicated Vendor table, or storing vendor data on the existing Account/Contact table. Pick one and stay consistent |
| Products | Released product master | Product number-based | Feeds sales/purchase order scenarios if you enable those maps later |
| Currencies | Currency reference data | Currency code | Near-universal dependency — most other maps need it enabled |
| Units / Unit groups | Unit-of-measure reference data | Unit symbol/code | Dependency for product-related maps |
Worth a heads-up to your CE team
The Party/Global Address Book model introduces a Contact for Customer/Vendor intersect table in Dataverse to represent the many-to-many relationship between contacts, customers, and vendors. If your CE team is used to a simpler Account/Contact model, this is the part that tends to cause the most "why is this here" questions during UAT — worth a short walkthrough with them ahead of go-live.
Illustrative: why dependencies matter
Enable the base maps before the map that depends on them — this is exactly what the "Show related table map(s)" dialog in Step 7 is prompting you to do.
Legal Entities ↔ Business Units
Legal entities are selected during the initial linking wizard, and each one becomes a Company record tied to a Dataverse Business Unit. You are not locked into that initial list.
- 1On the Dual-write table map list page, select Environment details.
- 2Open the Legal entities tab.
- 3Select Add legal entity, choose whether to skip initial writes for the entity you're adding, and Save.
This can be done live, without unlinking the environment — useful for phased rollouts or company acquisitions.
Gotcha to plan for
If the same real-world customer or vendor trades with more than one legal entity, dual-write creates one Dataverse record per legal entity — not a single merged record. This is expected behavior, not a bug, but it surprises teams who assumed Dataverse would hold one deduplicated record per customer. Set expectations with reporting/CE stakeholders before go-live rather than after.
Microsoft Entra ID Apps Used by Dual-Write
Here's the part most guides gloss over: for the core dual-write connection, you are not registering brand-new Entra applications from scratch. Microsoft ships two fixed, first-party application IDs specifically for the F&O↔Dataverse trust. What you're actually doing is creating the application user records that reference those existing IDs, on both sides. When you run the standard linking wizard, this happens automatically — you only do it by hand when recovering from a failed or broken link.
| Application ID | Purpose |
|---|---|
6f7d0213-62b1-43a8-b7f4-ff2bb8b7b452 | Lets Dataverse call into F&O |
2e49aa60-1bd3-43b6-8ab6-03ada3d9f08b | Used on both sides of the connection |
00000015-0000-0000-c000-000000000000 | Required only in Microsoft-managed (non-CHE) environments |
Done in F&O
Granting Dataverse access to F&O
- 1Open the F&O app, search for Microsoft Entra ID applications, and open that page.
- 2Select New, and add a client ID row for
6f7d0213-...b452. - 3On that row, select an application user that's enabled and has dual-write data management privileges.
- 4Repeat for
2e49aa60-...f08b. - 5Refresh the table list: Workspaces > Data management > Data entities, and separately the Framework parameters tile → Entity settings → Refresh entity list.
Done in Dataverse
Granting F&O access to Dataverse
Power Platform admin center → your environment → Settings → Users + permissions → Application users → New app user
- 1Create an application user for
00000015-...0000(skip if you're on a customer-managed CHE) and for2e49aa60-...f08b. - 2Assign each a security role granting Create/Read/Write/Delete on every table configured for dual-write.
- 3Add all dual-write app users to the Dual-Write App User role. Add Dual-Write Runtime User too for non-admins who create rows directly.
- 4Make sure everyone has Read access to the Company and currency exchange tables — global, and every dual-write user needs visibility into them.
Operational detail: ownership inheritance
The default team of the root business unit becomes the default owner of every row that comes in through dual-write. That team needs a security role assigned to it — but because of how team membership inheritance works, any user sitting in the root business unit will inherit read access to every dual-write row as a side effect. If that's not what you want, keep users out of the root business unit.
Operational detail: tenant consent
Tenant app consent used to be a separate manual step in this process. As of dual-write core solution version 1.0.16.0 and later, it's handled automatically — worth checking your installed solution version if you're following older internal runbooks that still list it as a step.
A different scenario: custom integrations
If you're building a separate custom integration alongside dual-write — a middleware service or Power Automate flow that also needs to call Dataverse or F&O APIs — that's a genuinely new app registration, not a dual-write configuration task. Go to the Microsoft Entra admin center → App registrations → New registration, record the Application (client) ID and Tenant ID, add the relevant API permissions (Dynamics CRM/Dataverse, and/or F&O's OData or custom services API), grant admin consent, then create a matching Dataverse application user for it exactly as described above.
If an Entra ID / Application User Is Missing
Symptoms this has happened
- The health check reports an app user ID that "doesn't exist."
- You see
DW9003errors ("Failed to connect to CRM/AX — ensure the service principal has the correct permissions"). - A 403 Forbidden during token exchange.
- An initial sync that fails outright with no other obvious cause.
F&O side
If the F&O-side client row is missing or corrupted
- 1Go to Microsoft Entra ID applications in F&O.
- 2If the row exists but is misbehaving (a common cause of persistent 403s during initial sync), delete it rather than editing it, then re-add the same client ID as a fresh row.
- 3Attach a valid, enabled application user with the right dual-write privileges to the new row.
Dataverse side
If the Dataverse-side application user is missing
- 1Power Platform admin center → your environment → Settings → Users + permissions → Application users → New app user.
- 2Search for the app by name or by the client ID from the table above.
- 3Assign a business unit, then assign the Dual-Write App User role (and Dual-Write Runtime User if applicable).
- 4Save.
Not sure which side is broken? Run the dual-write health check before guessing — it names the specific missing application user ID rather than making you hunt for it.
The Dual-Write Health Check
This is Microsoft's built-in diagnostic, and it's worth running proactively, not just when something's already on fire. In F&O, open the Dual-write page, and on the Action Pane select Health check. The same check also runs automatically as part of the initial linking wizard and the reset wizard.
What it checks, in order
1 · Prerequisite health check
Confirms system requirements are met, required Dataverse solutions are installed, and app users/permissions are all in place. All errors here must be resolved before the next stage runs.
2 · Dependency validation
| Code | Meaning | Fix |
|---|---|---|
DWDVEV1001 / DWFOEV1001 | Missing API Hub connection (Dataverse or F&O side) — may have been deleted in the Power Apps maker portal | Reset the dual-write connection |
DWDVEV1003 / DWFOEV1003 | A legal entity configured for dual-write doesn't exist as a matching Company record on the other side | Remove the mismatched company from the config, or reset the connection |
DWDVEV1004 / DWFOEV1004 | Stale dual-write configuration left behind after an environment change | Follow the cleanup steps in the live-sync troubleshooting guide |
DWFOEV1006 | The default team name for a business unit was renamed after linking, breaking the expected match | Reset the connection, or open a Microsoft Support ticket with the current default team details |
DWDVEV1007 | No default owning team set on a Company record | In the Power Apps maker portal, open the Company table, and set the Default owning team column for every company syncing with dual-write |
Run the health check before any major change — adding a legal entity, enabling a new table map, or after a backup/restore — rather than only after something breaks.
Common Issues and Day-2 Troubleshooting
| Issue | Likely cause | What to do |
|---|---|---|
| Can't open the Dual-write page at all | The data integration service is down | Self-service won't fix this — open a Microsoft support ticket to request a restart |
| Initial sync fails on a map with many lookup fields | Initial sync has a 10-lookup limit per map | Temporarily remove optional lookups, run initial sync, then add the remaining lookups back in a second pass |
| "Plugin registration failed" / "unable to build dual-write lookup metadata" | A dependent map isn't enabled, or a source/destination column is missing | Enable the dependent table maps first, then retry |
| 401 Unauthorized when adding a new table map | Only the original account that set up the link can add new maps | Use that account, or be deliberate about who owns setup from day one |
| 403 Forbidden tied to a specific app during initial sync | A corrupted Entra client entry | Delete and re-add the client row rather than editing it in place |
| New records aren't syncing after you resumed a map | A stopped map doesn't queue changes — only a paused one does | Confirm the map status is actually Running, not just "looks fine" in the UI |
| Duplicate customer/vendor records | Same party trading across multiple legal entities | Expected behavior — see the legal entities section above, not a defect to chase |
| Unexplained flood of sync errors | Updates to unmapped fields can trigger phantom sync attempts on both sides | Filter the (preview) Sync errors dashboard by entity/date, then bulk retry or dismiss |
Tools to reach for, in order of how often you'll use them
- 1Sync errors dashboard (preview) — a self-service view filterable by date, entity, and source system, with per-record retry or dismiss actions.
- 2Per-map activity log — a chronological history of everything a specific table map has gone through, with downloadable logs for deeper errors.
- 3Alert settings — configure email notification when an error threshold is crossed, and optionally let dual-write auto-pause or auto-stop itself. After changing alert settings, restart the affected table maps — the change doesn't take effect until you do.
- 4Trace logs (Dataverse/CE side) — Settings → Administration → System Settings → Customization tab, set custom workflow/plug-in tracing to All. Verbose, meant for deep support-level diagnosis; turn it back off once done.
Illustrative: an alert threshold
You define the threshold and the action — dual-write can pause or stop itself automatically rather than let a bad run keep failing silently.
Quick-Reference Checklist
Pre-launch checklist
- ✓Confirm F&O and Dataverse versions meet the current minimums, and both sit in the same tenant and datacenter
- ✓Decide and document who the "setup owner" account is (only they can add table maps later)
- ✓Uninstall Prospect-to-Cash if present
- ✓Rehearse the link on a sandbox — it isn't reversible without data loss on the real thing
- ✓Run the linking wizard; let the automatic health check pass before proceeding
- ✓Apply the dual-write solution packages you actually need
- ✓Enable table maps together with their dependencies, not one at a time
- ✓Confirm each map reaches Running, not just Initializing
- ✓Validate with one real record end to end
- ✓Set up alert thresholds and restart maps so the alerts take effect
- ✓If anything authentication-related breaks later, run the health check first — it names the exact missing app user rather than making you guess
The bottom line
Dual-write isn't a checkbox integration — it's an architectural commitment. Get the setup-owner account, the master data map dependencies, and the Entra application users right before you link a production environment, because unlinking later means data loss, not a rollback. Rehearse it on a sandbox, run the health check before every major change, and keep this page open the first time you see a DW error code.
Further Reading
Related reading
Integrating Social Media Engagement with Dynamics 365 Customer Insights – Journeys: What Actually Works in 2026
The native social-posting module is being retired, the old Hootsuite connector targets a different product, and X's API pricing has changed twice. Here's the architecture that actually holds up.
IntegrationDynamics 365 On-Premises Email Sync Is on Borrowed Time — Here's the Graph API Path Forward
EWS is being retired for Exchange Online, and Dynamics 365 CE on-premises has no first-party replacement. Here are the dates that matter and what a custom Graph API build actually involves.