An API that connects multiple Microsoft services, enabling data access and automation across platforms
A persistent tenant-specific 409 Conflict when the same hold can be created in Purview should be treated as an unresolved Graph/backend state conflict and escalated through the existing Microsoft support case with correlated request data; no published September 2026 endpoint change or eDiscovery-specific 409 condition is documented.
What the 409 establishes
Microsoft Graph defines 409 Conflict only as a request that conflicts with the resource’s current state. Retrying is specifically suggested for a concurrency violation, using Retry-After when supplied or exponential backoff otherwise.^1^
The legal-hold API documentation:
- Still supports
POST /security/cases/ediscoveryCases/{ediscoveryCaseId}/legalHolds. - Accepts
displayName, optionaldescription, and optionalcontentQuery. - Supports application permission
eDiscovery.ReadWrite.All. - Specifies
201 Createdfor success, but does not document endpoint-specific reasons for409.^2^
Since duplicate names, concurrent operations, and transient retries have already been ruled out—and portal creation succeeds—repeating those checks is unlikely to identify this case. The public Graph known-issues page also does not identify an eDiscovery legalHolds creation issue matching this behavior.^3^
Inspect both Graph and Purview policy stores
Use both interfaces because they can expose different symptoms of an incomplete or inconsistent policy operation.
- Enumerate every policy Graph can see, preserving IDs, status, errors, and timestamps:
GET https://graph.microsoft.com/v1.0/security/cases/ediscoveryCases/{caseId}/legalHolds
Authorization: Bearer {token}
The list operation returns the hold-policy collection.^4^ Relevant states are Pending, Error, and Success; the resource also exposes an errors collection.^5^
- Connect to Security & Compliance PowerShell with an account assigned the required Purview permissions, then inspect all policies for the case:
$policies = Get-CaseHoldPolicy -Case "<case name>" -DistributionDetail
$policies | Format-List Name,Guid,CaseId,DistributionStatus,*Error*
$policies | ForEach-Object {
Get-CaseHoldPolicy -Identity $_.Guid -DistributionDetail |
Select-Object -ExpandProperty DistributionResults
}
Get-CaseHoldPolicy is the supported cmdlet for viewing case-hold policies; -DistributionDetail provides deployment and affected-location details.^6^
- Compare the Graph IDs and PowerShell GUIDs, looking for:
- A policy present in PowerShell but absent from Graph or the portal.
-
Pending/In progressorPending deletionstate that never completes. -
InternalError,PolicySyncTimeout, orPolicyNotifyErrorin distribution results.
A policy that genuinely exists but has a failed distribution can be retried through:
POST https://graph.microsoft.com/v1.0/security/cases/ediscoveryCases/{caseId}/legalHolds/{holdId}/retryPolicy
Authorization: Bearer {token}
Success returns 204 No Content.^7^ For InternalError, Microsoft’s documented resolution is to contact Support with the policy name, service, result code/message, and diagnostics.^8^
Do not delete an active or unidentified hold
If an unwanted policy is visible and its identity has been conclusively matched, the supported v1.0 deletion is:
DELETE https://graph.microsoft.com/v1.0/security/cases/ediscoveryCases/{caseId}/legalHolds/{holdId}
Authorization: Bearer {token}
Successful deletion returns 204 No Content.^9^
For a PowerShell-visible policy, Remove-CaseHoldPolicy supports identity by name or GUID and includes -ForceDeletion; Microsoft also states that the corresponding case-hold rule should be removed.^10^ This is destructive and can remove preservation, so it should not be used merely to test whether the 409 disappears.
Invoke-HoldRemovalAction is intended to view or remove holds applied to mailboxes or SharePoint sites, and removal requires the Compliance Administrator role.^11^ It is not documented as a general repair command for a hidden policy object blocking POST /legalHolds; use it only when Support or location-level diagnostics identify an invalid/orphaned hold on a specific mailbox or site.
Information to attach to the support case
For one failed request per affected tenant, provide privately:
- UTC timestamp.
- Tenant and case IDs.
-
request-idandclient-request-id. - Full response status, headers, error
code,message, andinnerError. - Sanitized request body.
- Whether
Retry-Afterwas returned. - Graph policy enumeration and
Get-CaseHoldPolicy -DistributionDetailoutput. - A portal-created control hold’s ID and creation timestamp.
- Confirmation that the same app and payload succeed in unaffected tenants.
Ask Support to correlate the Graph request ID with the eDiscovery/Purview backend logs and check for an incomplete policy-creation transaction, hidden policy/rule, or tenant synchronization inconsistency. Public APIs do not provide a supported operation for enumerating and clearing an object that is invisible to both Graph and Purview PowerShell.
References
- Microsoft Graph error responses and resource types
- Create ediscoveryHoldPolicy - Microsoft Graph v1.0
- Known issues in Microsoft Graph
- List ediscoveryHoldPolicies
- ediscoveryHoldPolicy resource type
- Get-CaseHoldPolicy-Syntax
- ediscoveryHoldPolicy: retryPolicy
- Resolve eDiscovery hold errors
- Delete ediscoveryHoldPolicy
- Remove-CaseHoldPolicy-Syntax
- Invoke-HoldRemovalAction-Description