---
title: "Troubleshooting Guide: Top 30 Errors During Dynamics 365 On-Prem → Online Migrations (OP2OL) "
slug: dynamics-365-migration-troubleshooting-error-codes
date: 2026-02-03
author: Raaj
categories: [Microsoft Dynamics 365]
excerpt: "Migrating from Microsoft Dynamics 365 On-Premise to Online (OP2OL) involves complex data transformation. This guide serves as a technical reference for the 30 most common migration failures, including specific error codes (0x8004...), SQL transaction logs, and API throttling limits."
canonical: https://clonepartner.com/blog/dynamics-365-migration-troubleshooting-error-codes/
---

# Troubleshooting Guide: Top 30 Errors During Dynamics 365 On-Prem → Online Migrations (OP2OL) 


- **Last Verified:** February 2, 2026
- **Platform:** Dynamics 365 CE (v9.x) / Dataverse API v9.2
- **Citation Policy:** Technical limits sourced directly from [Microsoft Learn](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/api-limits) and [Azure SQL Database documentation](https://learn.microsoft.com/en-us/azure/azure-sql/database/resource-limits-dtu-single-databases).

## Section 1: Critical Telemetry & Benchmarks

*Use these verified ranges to configure your ETL tools (ADF, KingswaySoft, SSIS).*

| **Metric** | **Safe Threshold** | **Failure Threshold** | **Context** |
| --- | --- | --- | --- |
| **SQL Timeout** | &lt; 120 Seconds | &gt; 120 Seconds | Hard limit for TDS/SQL connections. Source: [TDS Limits](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/dataverse-sql-query#limitations) |
| **Batch Size (Complex)** | 250 - 500 records | &gt; 1,000 records | For *Quotes, Orders, Cases* (Entities with heavy plugin logic). |
| **Batch Size (Simple)** | 1,000 - 2,000 records | &gt; 5,000 records | For *Tasks, Contacts, Leads*. |
| **Concurrency** | 2 - 4 Threads | &gt; 52 Threads | Per User Limit. Source: [Service Protection API](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/api-limits?tabs=sdk) |
| **Attachment Size** | &lt; 25 MB | &gt; 35 MB | Hard Exchange Online limit. Source: [Exchange Online Limits](https://learn.microsoft.com/en-us/office365/servicedescriptions/exchange-online-service-description/exchange-online-limits) |

## Section 2: The Master Error Database (01–30)

### 01. System.TimeoutException (SQL Execution Limit)

- **Category:** Infrastructure / SQL
- **Root Cause:** The query execution exceeded the hard 2-minute (120s) limit on the Dataverse SQL layer. This frequently occurs when reading "heavy" entities like `Annotation` (Notes) or `ActivityPointer` where table sizes exceed 1GB.
- **Official Citation:** [Dataverse SQL Query Limitations (2-minute limit)](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/dataverse-sql-query#limitations)
- **Technical Resolution:** Do not use standard OData (`/api/data/v9.2/`) for bulk extraction of >500k rows. Use the **TDS Endpoint (SQL)** with strict pagination.
- **Reproducible Artifact (T-SQL):**

```sql
-- BAD: SELECT * FROM [Annotation] (Will Timeout)
-- GOOD: Deterministic Pagination using OFFSET/FETCH
SELECT [AnnotationId], [Subject], [NoteText], [CreatedOn]
FROM [Annotation]
WHERE [CreatedOn] >= '2023-01-01'
ORDER BY [CreatedOn] ASC
OFFSET 0 ROWS FETCH NEXT 5000 ROWS ONLY;
```

- **Verification:** Run the query in SSMS connected to the TDS endpoint. If execution time > 55s, reduce batch size to 2,000.

### 02. Generic Plugin Error (0x80040216)

- **Category:** Server-Side Logic
- **Root Cause:** A synchronous plugin registered on `Pre-Operation` or `Post-Operation` is failing. This blocks the transaction.
- **Official Citation:** [Bypass Custom Business Logic](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/bypass-custom-business-logic)
- **Technical Resolution:** Do not disable plugins manually. Use the `BypassCustomPluginExecution` parameter in your API calls. This requires the migration user to have the `prvBypassCustomPluginExecution` privilege.
- **Reproducible Artifact (HTTP Header):**

```javascript
POST [Organization URI]/api/data/v9.2/accounts HTTP/1.1
MSCRM.BypassCustomPluginExecution: true
Content-Type: application/json

{
  "name": "Migrated Account",
  "creditlimit": 10000
}
```

- **Verification:** Check the **Plugin Trace Log** table in Dataverse. If the bypass is working, no logs will be generated for the migration user during the load.

### 03. Record Is Unavailable (Referential Integrity / Circular Reference)

- **Category:** Data Mapping
- **Root Cause:** Record A references Record B, but Record B has not been created yet. Common in "Parent Account" scenarios where Account X is the parent of Account Y, but Account Y is processed first.
- **Technical Resolution:** Implement **Multi-Pass Ingestion**.
- 
  1. **Pass 1 (Create):** Insert all records with Lookup fields set to `NULL`.
  2. **Pass 2 (Update):** Iterate through the source data again and update only the Lookup fields.
- **Reproducible Artifact (C# Logic):**

```csharp
// Pass 1: Create Stub
Entity account = new Entity("account");
account["name"] = "Child Branch";
account["parentaccountid"] = null; // Intentional Null
Guid createdId = service.Create(account);

// Pass 2: Patch Relationship (After all accounts exist)
Entity patch = new Entity("account");
patch.Id = createdId;
patch["parentaccountid"] = new EntityReference("account", parentGuid);
service.Update(patch);
```

- **Telemetry Threshold:** If "Missing Reference" errors exceed 5% of a batch, pause and verify your load order (e.g., Users > Accounts > Contacts).

### 04. Generic SQL Error (Transaction Log Full)

- **Category:** Database Constraints
- **Root Cause:** Massive bulk inserts are filling the SQL transaction log buffer on the target instance before a commit can occur.
- **Official Citation:** [Azure SQL Resource Limits (DTU-based)](https://learn.microsoft.com/en-us/azure/azure-sql/database/resource-limits-dtu-single-databases)
- **Technical Resolution:** Dataverse does not allow you to change the Recovery Model to "Simple." You must control this via client-side batching. Reduce your `ExecuteMultipleRequest` batch size.
- **Benchmark:**
- 
  - **Safe:** 10 requests per batch.
  - **Risky:** > 1000 requests per batch (High risk of log overflow).
- **Verification:** Monitor the **Dataverse Analytics** dashboard > "SQL Failures."

### 05. ISV Code Aborted (Legacy Assembly)

- **Category:** Legacy Extensibility
- **Root Cause:** Custom Workflow Activities or Plugins are using unsupported .NET Framework versions (e.g., 4.5.2) or deprecated `Xrm.Page` references.
- **Official Citation:** [Supported Extensions & .NET Framework](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/)
- **Technical Resolution:** Recompile all custom assemblies to **.NET 4.6.2** (or 4.7.1) before migration.
- **Verification:** Run the **Power Apps Solution Checker** on your solution zip file. It will flag `Type or namespace not found` errors for deprecated code.

### 06. Service Protection Limit (429 Too Many Requests)

- **Category:** API Throttling
- **Root Cause:** The migration user has exceeded 6,000 requests within a 5-minute sliding window.
- **Official Citation:** [Service Protection API Limits](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/api-limits)
- **Technical Resolution:** Do not use a fixed `Thread.Sleep()`. You must parse the `Retry-After` header returned by the 429 response.
- **Reproducible Artifact (C# / .NET SDK):**

```csharp
try {
    service.Execute(request);
}
catch (FaultException<OrganizationServiceFault> ex) {
    if (ex.Detail.ErrorCode == -2147015902) { // 429 Code
        // Extract the 'Retry-After' duration mandated by the server
        int retrySeconds = 5; // Default fallback
        if (ex.Detail.ErrorDetails.Contains("Retry-After")) {
            retrySeconds = Convert.ToInt32(ex.Detail.ErrorDetails["Retry-After"]);
        }
        Thread.Sleep(retrySeconds * 1000);
        // Retry logic here...
    }
}
```

### 07. Principal with Id Does Not Exist

- **Category:** Security / User Mapping
- **Root Cause:** The `OwnerId` (User or Team GUID) in the source data does not exist in the target Entra ID (Azure AD).
- **Technical Resolution:** Create a **User Mapping Table**. Do not attempt to migrate users with their old On-Prem GUIDs unless you have pre-seeded the target with those exact GUIDs (which is rare).
- **Artifact (Mapping Strategy):** | Source GUID | Target GUID | Source Name | Target Name | | :--- | :--- | :--- | :--- | | `1111-aaa...` | `2222-bbb...` | John Doe | John Doe | | `3333-ccc...` | `9999-zzz...` | (Terminated User) | "Stub User" / Admin |
- **Verification:** Perform a `WhoAmI` request or simple `Retrieve` on the target `systemuser` table using the Target GUID before starting the batch.

### 08. Invalid Argument (Picklist / OptionSet)

- **Category:** Data Schema
- **Root Cause:** The source data contains an integer value (e.g., `999`) that is not defined in the target OptionSet metadata.
- **Technical Resolution:**
- 
  - **Option A:** Map invalid values to a "Default" (e.g., `999` -> `1`).
  - **Option B (Admin):** Programmatically create the missing option using `InsertOptionValueRequest`.
- **Reproducible Artifact (SDK Request):**

```csharp
var request = new InsertOptionValueRequest {
    AttributeLogicalName = "industrycode",
    EntityLogicalName = "account",
    Value = 999, // The missing value
    Label = new Label("Legacy Industry", 1033)
};
service.Execute(request);
```

### 09. Attachment Size Exceeds Limit

- **Category:** File Storage
- **Root Cause:** Files in `Annotation` or `ActivityMimeAttachment` exceed the default 5MB limit.
- **Official Citation:** [Exchange Online Message Limits](https://learn.microsoft.com/en-us/office365/servicedescriptions/exchange-online-service-description/exchange-online-limits)
- **Technical Resolution:**
- 
  1. Update **System Settings** > **Email** > **Max file size** to `131,072` KB (128 MB).
  2. For files > 128 MB, migrate to Azure Blob Storage and leave a URL link.
- **Verification:** Attempt to upload a 10MB file via the Unified Interface. If it fails, the setting has not propagated.

### 10. Duplicate Key Violation

- **Category:** SQL Constraints
- **Root Cause:** Attempting to insert a record with a Primary Key (GUID) that already exists in the target.
- **Technical Resolution:** Switch from `CreateRequest` to `UpsertRequest`. This operation checks for existence: if the record exists, it updates it; if not, it creates it.
- **Reproducible Artifact (C#):**

```csharp
var account = new Entity("account", new Guid("source-guid-here"));
account["name"] = "Updated Name";

var request = new UpsertRequest { Target = account };
var response = (UpsertResponse)service.Execute(request);

// response.RecordCreated tells you if it was an Insert or Update
```

### 11. Privilege Denied (SecLib::AccessCheckEx Failed)

- **Category:** Security Roles
- **Root Cause:** The Application User or Service Principal performing the migration lacks the specific privilege (e.g., `prvCreateAccount` or `prvAppendTo`) for the entity being migrated.
- **Official Citation:** [Dataverse Security Roles & Privileges](https://learn.microsoft.com/en-us/power-platform/admin/security-roles-privileges)
- **Technical Resolution:** Do not rely on a custom "Migration Role." Assign the standard **System Administrator** role to the Application User. If using a Service Principal, ensure the Application User is enabled and the Client Secret has not expired.
- **Verification:** Navigate to **Power Platform Admin Center** > **Environments** > **Users**. Select the Application User and click "Manage Roles" to confirm "System Administrator" is checked.

### 12. Max Depth Exceeded (Infinite Loop)

- **Category:** Workflow / Business Logic
- **Root Cause:** A synchronous workflow or plugin is triggering itself recursively. Dataverse enforces a hard "Max Depth" limit (default is 8) to prevent infinite loops.
- **Official Citation:** [Message Processor & Max Depth](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/org-service/overview)
- **Technical Resolution:** You must deactivate all workflows and Power Automate flows triggered by "Record Creation" or "Record Update" on the target entities *before* migration starts.
- **Reproducible Artifact (PowerShell):**

```javascript
# Use the Microsoft.Xrm.Data.PowerShell module to disable workflows
$workflows = Get-CrmRecords -EntityLogicalName workflow -FilterAttribute statecode -FilterOperator eq -FilterValue 1 # 1 = Active
foreach ($wf in $workflows) {
    Disable-CrmRecord -EntityLogicalName workflow -Id $wf.workflowid
    Write-Host "Disabled Workflow: $($wf.name)"
}
```

- **Verification:** Attempt to manually create a record in the UI. If it triggers a 5-second loading spinner followed by an error, a process is still active.

### 13. Date Out of Range

- **Category:** Data Format
- **Root Cause:** Source data contains dates older than `1/1/1753` (SQL MinDate) or `1/1/1900` (Dataverse MinDate). This is common in legacy "Date of Birth" fields or placeholder dates.
- **Official Citation:** [DateTimeAttributeMetadata Class](https://learn.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.metadata.datetimeattributemetadata?view=dataverse-sdk-latest)
- **Technical Resolution:** Implement a transformation rule in your ETL: `IF SourceDate < '1900-01-01' THEN SET TargetDate = NULL`
- **Reproducible Artifact (C# Transformation):**

```csharp
DateTime? safeDate = sourceDate;
if (sourceDate.HasValue && sourceDate.Value.Year < 1900)
{
    safeDate = null; // Or use new DateTime(1900, 1, 1);
}
entity["birthdate"] = safeDate;
```

### 14. Entity Reference Cannot Be Found

- **Category:** Polymorphic Lookups
- **Root Cause:** A lookup field (e.g., `parentcustomerid`) points to a GUID that does not exist in *either* the Account or Contact table. This often happens when the referenced record was deleted in the source but the relationship was not cascaded.
- **Technical Resolution:** Do not fail the entire batch. Catch the `FaultException`, log the specific GUID as a "Broken Link," and retry the create operation *without* that specific lookup value.
- **Verification:** Query the `Failures` table in your migration tool. If you see >10% failure rate, run a SQL query on the source to identify "Orphaned Records" before migrating.

### 15. Currency Mismatch (TransactionCurrencyId)

- **Category:** Finance / Multi-Currency
- **Root Cause:** You are migrating a record with a `Money` field (e.g., `revenue`), but the `transactioncurrencyid` lookup is null, or the referenced currency does not exist in the target.
- **Official Citation:** [Transaction Currency (Currencies) Entity](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/reference/entities/transactioncurrency)
- **Technical Resolution:**
- 
  1. Migrate the `transactioncurrency` table **first**.
  2. Ensure the `isocurrencycode` (e.g., USD, EUR) matches exactly.
  3. If the source `transactioncurrencyid` is null, default it to the target organization's Base Currency.

### 16. String or Binary Data Would Be Truncated

- **Category:** Data Schema
- **Root Cause:** The text in the source column is longer than the `MaxLength` defined in the target Dataverse column (e.g., Source: 200 chars, Target: 100 chars).
- **Technical Resolution:**
- 
  - **Fix A (Preferred):** Go to the **Power Apps Maker Portal**, select the Column, and increase "Maximum Character Count."
  - **Fix B (Data Loss):** Truncate the string in your ETL script.
- **Reproducible Artifact (SQL Truncation):**

```sql
-- Safer to truncate than to fail
SELECT LEFT([Description], 2000) as [Description], [Subject]
FROM [Incident]
```

### 17. Entity State is Invalid

- **Category:** Status / Lifecycle
- **Root Cause:** Attempting to create a record directly in a "Resolved" or "Inactive" state (e.g., `statecode=1`). Some system entities do not allow creation in a closed state.
- **Official Citation:** [Update Entity State (SetStateRequest)](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/org-service/entity-operations-update-delete?tabs=late)
- **Technical Resolution:** **Two-Step Ingestion:**
- 
  1. Create the record in `Active` state (`statecode=0`).
  2. Send a separate `UpdateRequest` or `SetStateRequest` to close it.
- **Verification:** Compare the count of `Active` vs `Inactive` records in Source vs Target.

### 18. Root Element is Missing (XML)

- **Category:** Data Structure / Notes
- **Root Cause:** You are migrating a `Note` (Annotation) that contains an attached file, but the `documentbody` (Base64 string) is corrupt, empty, or the `mimetype` is missing.
- **Technical Resolution:** Validate that `documentbody` is not null and is a valid Base64 string. `IF documentbody IS NOT NULL AND mimetype IS NULL SET mimetype = 'application/octet-stream'`

### 19. Managed Property Error

- **Category:** Solution Layering
- **Root Cause:** You are trying to update a component (like a View, Form, or Attribute) that is part of a **Managed Solution** where `IsCustomizable` is set to `False`.
- **Official Citation:** [Managed Properties](https://learn.microsoft.com/en-us/power-apps/maker/data-platform/set-managed-properties-for-field)
- **Technical Resolution:** You cannot directly modify these components via migration API. You must install a new version of the Managed Solution that contains the desired changes (e.g., longer field length).

### 20. Missing Dependency

- **Category:** Solution Import
- **Root Cause:** You are importing a Solution file (`.zip`) that references a component (e.g., a Global OptionSet or a 3rd Party DLL) that does not exist in the target environment.
- **Technical Resolution:**
- 
  1. Unzip the solution and open `solution.xml`.
  2. Search for the `<MissingDependency>` tag to identify the missing GUID/Name.
  3. Install the prerequisite solution first.
- **Verification:** The import log will explicitly list the "Required Solution Name."

### 21. Attachment Limit Exceeded (Exchange Sync)

- **Category:** Email Integration
- **Root Cause:** A migrated email contains an attachment larger than **35 MB**. While Dataverse allows files up to 128 MB, **Exchange Online** has a hard transmission limit of 35 MB (after Base64 encoding overhead).
- **Official Citation:** [Exchange Online Limits (Message Limits)](https://learn.microsoft.com/en-us/office365/servicedescriptions/exchange-online-service-description/exchange-online-limits)
- **Technical Resolution:** You cannot sync these emails to Outlook. **Strategy:** Detect attachments > 25 MB during migration. Strip the attachment, upload it to Azure Blob Storage, and append the Blob URL to the email body text.
- **Verification:** Check the "Server-Side Synchronization" dashboard for "Permanent Failures" with error code `ExchangeAttachmentLimit`.

### 22. Workforce / Resource Constraint

- **Category:** Field Service
- **Root Cause:** Creating a `BookableResource` record fails because the associated User or Contact does not have a valid **Calendar** (Work Hours) defined in the target.
- **Official Citation:** [Set up bookable resources](https://learn.microsoft.com/en-us/dynamics365/field-service/set-up-bookable-resources)
- **Technical Resolution:** **Order of Operations:**
- 
  1. Migrate `calendar` and `calendarrule` entities.
  2. Migrate `systemuser`.
  3. Migrate `bookableresource`. *Note: If the Calendar is missing, the scheduling engine cannot instantiate the resource.*

### 23. Duplicate Lookup Reference

- **Category:** Data Quality
- **Root Cause:** Ambiguous resolution. You are mapping a lookup based on "Name" (e.g., `parentcustomerid = "John Smith"`), but two records named "John Smith" exist in the target.
- **Technical Resolution:** **Strict GUID Mapping:** Never use text-based lookup resolution for migration. Always map Source GUID to Target GUID.
- **Reproducible Artifact (FetchXML Check):**

```sql
<fetch aggregate="true">
  <entity name="contact">
    <attribute name="fullname" alias="name_count" aggregate="count"/>
    <attribute name="fullname" alias="name_group" groupby="true"/>
    <order alias="name_count" descending="true"/>
  </entity>
</fetch>
```

### 24. Team Template Mismatch

- **Category:** Access Teams
- **Root Cause:** You are migrating records that use **Access Teams** (auto-created teams), but the `teamtemplateid` refers to a template that does not exist in the target environment.
- **Technical Resolution:** Access Team Templates are not solution-aware. You must manually recreate them in the Target environment and map the *Old Template ID* to the *New Template ID* in your migration script.

### 25. Invalid Plugin Assembly (Security)

- **Category:** Security / Sandbox
- **Root Cause:** The assembly contains code forbidden in the Dynamics 365 **Sandbox** isolation mode (Partial Trust). Common blockers: `System.IO` (File access), `System.Reflection`, or direct SQL connections.
- **Official Citation:** [Plug-in isolation, trusts, and statistics](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/plug-ins)
- **Technical Resolution:** Refactor the code. Move heavy logic or prohibited namespaces to **Azure Functions**, which can be triggered by a Webhook or Service Bus.

### 26. Business Process Flow (BPF) Error

- **Category:** Process Automation
- **Root Cause:** The `traversedpath` field contains a comma-separated list of Stage GUIDs. If the BPF definition in the target has different Stage GUIDs than the source, the record will fail to load.
- **Official Citation:** [Business process flow entity serialization](https://learn.microsoft.com/en-us/power-automate/business-process-flows-overview)
- **Technical Resolution:** Do not migrate the `traversedpath` string directly. You must create a "Stage Map" (Source Stage GUID -> Target Stage GUID) and reconstruct the path string during transformation.

### 27. PrincipalAccess Missing (POA Table)

- **Category:** Sharing (Critical)
- **Root Cause:** The `PrincipalObjectAccess` (POA) table governs "Share" and "Assign" rights. Migration fails if the `PrincipalId` (User) or `ObjectId` (Record) does not exist yet.
- **Official Citation:** [Use Record Sharing to Manage Access](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/security-sharing-assigning)
- **Technical Resolution:** **The "Caboose" Strategy:** Migration of the POA table must be the absolute **last step** of the entire project.
- 
  - Step 1: Migrate Users & Teams.
  - Step 2: Migrate All Data.
  - Step 3: Migrate POA Table.
- **Reproducible Artifact (SDK Request):**

```csharp
// Use GrantAccessRequest, not Create. 
// Direct SQL insert into POA is NOT supported in Online.
var grantRequest = new GrantAccessRequest {
    PrincipalAccess = new PrincipalAccess {
        Principal = new EntityReference("systemuser", userId),
        AccessMask = AccessRights.ReadAccess | AccessRights.WriteAccess
    },
    Target = new EntityReference("account", accountId)
};
service.Execute(grantRequest);
```

### 28. SQL Connection Closed

- **Category:** Connectivity
- **Root Cause:** Transient network failure between your On-Premise server and the Azure Data Center, causing the `SqlConnection` to drop.
- **Technical Resolution:** Configure the connection string to handle transient failure.
- **Artifact (Connection String):** `Server=tcp:org.crm.dynamics.com,1433;Database=org;Authentication=ActiveDirectoryPassword;ConnectRetryCount=3;ConnectRetryInterval=10;`

### 29. Web Resource Content Invalid

- **Category:** UI / JavaScript
- **Root Cause:** JavaScript files contain unsupported DOM manipulation methods like `document.getElementById` or `$("#id")`, which fail in the **Unified Interface**.
- **Technical Resolution:** Run the **Solution Checker**. Replace all jQuery/DOM calls with the Client API (`formContext.getControl()`).

### 30. Portal/Site Setting Missing

- **Category:** Power Pages (Portals)
- **Root Cause:** Portal configuration (Adxstudio) relies on specific GUIDs for "Site Settings" and "Snippets." Standard data loaders often generate new GUIDs, breaking the portal linkage.
- **Technical Resolution:** Use the **Configuration Migration Tool** (CMT) provided in the SDK. It supports "Schema validation" and maintains referential integrity specifically for Portal entities.

## Section 2: Deep Dive – The "Migration Killers"

#### 1. The "Sandbox Isolation" Trap (System.Security.SecurityException)

**The Error:** "Request for the permission of type 'System.Security.Permissions.SecurityPermission' failed." **The Context:** On-Premise environments allowed "Full Trust" plugins. Dynamics 365 Online enforces **Sandbox Mode** (Partial Trust). **Why it happens:** Your legacy code tries to access file paths, registry keys, or external network calls directly. **The Fix:**

1. **Audit:** Run the "Custom Code Validation Tool" from XrmToolBox.
2. **Refactor:** Move external calls to **Azure Functions** triggered by Webhooks.
3. **ClonePartner Approach:** We bypass this by migrating data *directly* to the SQL layer via APIs, bypassing the plugin execution pipeline entirely during the initial load (BypassCustomPluginExecution option).

#### 2. The Circular Reference Deadlock

**The Error:** "Record A requires Record B, but Record B requires Record A." **The Context:** Common in Account/Contact relationships (Primary Contact vs. Parent Account). **The Fix:**

- **Pass 1:** Create Record A with the Lookup field *empty*.
- **Pass 2:** Create Record B pointing to Record A.
- **Pass 3:** Update Record A to point to Record B.
- *Tip:* Using standard "Flat File" importers often fails here. You need a script that supports "Multi-Pass" ingestion.

#### 3. The "2-Minute" SQL Timeout

**The Error:** SqlException: Timeout expired. **The Context:** Dynamics 365 Online has a hard limit on SQL execution time (usually 2 minutes) from the application layer. Heavy join queries in your migration source will kill the connection. **The Fix:**

- **Do not use OData** for massive reads. Use **TDS Endpoint** (Preview) or fetch data in simplified batches.

**Index:** Ensure your SystemUserId, StateCode, and CreatedOn columns are indexed in the source SQL DB before export.

> Book a free consultation to understand how ClonePartner can help you migrate
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30&utm_source=blog&utm_medium=button&utm_campaign=demo_bookings&utm_content=cta_click&utm_term=demo_button_click)

## Frequently asked questions

### Can I migrate On-Premise SQL directly to Dataverse?

No. You cannot restore a .bak file to Dataverse. You must use a migration tool (ADF, Scribe, or Custom Scripts) to map the schema and transfer data via API.

### How do I handle "CreatedOn" date changes?

By default, creating a record resets CreatedOn to "today." To preserve history, you must map the source CreatedOn field to the overriddencreatedon field in the target.

### Why is my migration failing on "OwnerId"?

You cannot migrate a record if the owner (user) is disabled or missing in Office 365. You must map inactive users to a generic "Stub User" or "System Admin" to preserve the record.
