Fix “List cannot be deleted while on hold or retention policy” Error on SharePoint Online

Problem: When trying to delete a document library in SharePoint Online, it gave the following error message: “List cannot be deleted while on hold or retention policy.”

list cannot be deleted while on hold or retention policy

Solution:

As the error message says, the List cannot be deleted while on hold or retention policy. This error is due to the site being under hold or compliance policy. When you delete a list item or a document in SharePoint, it goes to the site’s recycle bin, and a copy of the item is sent to the Preservation Hold library. So, to delete a list, you must delete all its files and subfolders first. Otherwise, you should exclude the site from the retention policy under Office 365 compliance center.

You can quickly check if the Microsoft SharePoint site is under hold by going to:

  1. Office 365 Admin Center >> Admin centers >> Security & Compliance >> Search & investigation
  2. Click on eDiscovery, and check if you have created any cases >> If you see any cases, click Open
  3. Under Hold, check if you see any sites.  

Alternatively, You can go to Settings >> Site Contents >> Check if there is a special library called “Preservation Hold Library”.

Deleting files in each folder could be haunting, especially with a deep folder structure. Fortunately, we have PowerShell to relieve the burden.

PowerShell to Clear Document Library’s Content and then Delete

This PowerShell script deletes all files, sub-folders, and the given document library in SharePoint Online.

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

#Variables
$SiteURL = "https://crescent.sharepoint.com/Sites/Marketing"
$LibraryName = "Branding Templates"
 
#Function to Delete all files and Sub-folders of a given Folder
Function Empty-SPOFolder([Microsoft.SharePoint.Client.Folder]$Folder)
{
    Try {
        #Get All Files from the Folder
        $Files = $Folder.Files
        $Ctx.Load($Files)
        $Ctx.ExecuteQuery()
  
        #Iterate through each File in the folder
        Foreach($File in $Files)
        {
            #Delete the file
            $Folder.Files.GetByUrl($File.ServerRelativeUrl).Recycle() | Out-Null
            Write-host -f Green "Deleted File '$($File.Name)' from '$($File.ServerRelativeURL)'"
        }
        $Ctx.ExecuteQuery()
  
        #Process all Sub Folders of the given folder
        $SubFolders = $Folder.Folders
        $Ctx.Load($SubFolders)
        $Ctx.ExecuteQuery()
        Foreach($Folder in $SubFolders)
        {
            #Exclude "Forms" and Hidden folders
            If( ($Folder.Name -ne "Forms") -and (-Not($Folder.Name.StartsWith("_"))))
            {
                #Call the function recursively to empty the folder
                Empty-SPOFolder -Folder $Folder
 
                #Delete the folder
                $Ctx.Web.GetFolderById($Folder.UniqueId).Recycle() | Out-Null
                $Ctx.ExecuteQuery()
                Write-host  -f Green "Deleted Folder:"$Folder.ServerRelativeUrl
            }
        }
    }
    Catch {
    write-host -f Red "Error:" $_.Exception.Message
    }
}
 
Try {
    #Get Credentials to connect
    $Cred= Get-Credential
 
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
   
    #Get the Library
    $Library = $Ctx.web.Lists.GetByTitle($LibraryName)
    $RootFolder = $Library.RootFolder
    $Ctx.Load($Library)
    $Ctx.Load($RootFolder)
    $Ctx.executeQuery()

    #Call the function to empty Folder
    Empty-SPOFolder $RootFolder
 
    #Delete the Document Library
    $Library.Recycle() | Out-Null
    $Ctx.ExecuteQuery() 
    Write-host  -f Green "Deleted Document Library Successfully!"
}
Catch {
    write-host -f Red "Error:" $_.Exception.Message
}
There is an easier way : Use “File Explorer” view or OneDrive Sync to delete all files and folders from a SharePoint Online Document Library in one shot!

Delete Document Library in Retention Hold using PnP PowerShell

Let’s fix the “list cannot be deleted while on hold or retention policy” error on SharePoint Online by deleting all files and folders first and then the document library using PnP PowerShell. Please note, if a file is checked out, you can’t delete it! It must be checked in to be able to delete. PowerShell to Bulk Check In All Documents in SharePoint Online

#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/Marketing"
$ListName = "Branding Templates"

#Connect to the Site
Connect-PnPOnline -URL $SiteURL -Credentials (Get-Credential)

#Get the web & document Library
$Web = Get-PnPWeb
$List = Get-PnPList -Identity $ListName

#Function to delete all Files and sub-folders from a Folder
Function Empty-PnPFolder([Microsoft.SharePoint.Client.Folder]$Folder)
{
    #Get the site relative path of the Folder
    If($Folder.Context.web.ServerRelativeURL -eq "/")
    {
        $FolderSiteRelativeURL = $Folder.ServerRelativeUrl
    }
    Else
    {        
        $FolderSiteRelativeURL = $Folder.ServerRelativeUrl.Replace($Folder.Context.web.ServerRelativeURL,[string]::Empty)
    }

    #Get All files in the folder
    $Files = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderSiteRelativeURL -ItemType File
    
    #Delete all files in the Folder
    ForEach ($File in $Files)
    {
        #Delete File
        Remove-PnPFile -ServerRelativeUrl $File.ServerRelativeURL -Force -Recycle
        Write-Host -f Green ("Deleted File: '{0}' at '{1}'" -f $File.Name, $File.ServerRelativeURL)        
    }

    #Process all Sub-Folders
    $SubFolders = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderSiteRelativeURL -ItemType Folder
    Foreach($SubFolder in $SubFolders)
    {
        #Exclude "Forms" and Hidden folders
        If( ($SubFolder.Name -ne "Forms") -and (-Not($SubFolder.Name.StartsWith("_"))))
        {
            #Call the function recursively
            Empty-PnPFolder -Folder $SubFolder

            #Delete the folder
            $ParentFolderURL = $FolderSiteRelativeURL.TrimStart("/")
            Remove-PnPFolder -Name $SubFolder.Name -Folder $ParentFolderURL -Force -Recycle
            Write-Host -f Green ("Deleted Folder: '{0}' at '{1}'" -f $SubFolder.Name, $SubFolder.ServerRelativeURL)
        }
    }
}

#Get the Root Folder of the Document Library and call the function to empty folder contents recursively
Empty-PnPFolder -Folder $List.RootFolder

#Now delete the document library
Remove-PnPList -Identity $ListName -Recycle -Force
Write-host -f Green "Document Library Deleted Successfully!"

If you just want to clear the document library without deleting the library, comment line#50 – Remove-PnPList. Here is another post on deleting all files and folders from a document library: SharePoint Online: How to Delete All Files in a Document Library using PowerShell?

PnP PowerShell to Empty a SharePoint Online Document Library

The above script just works fine with smaller libraries of < 5000 files. But on larger libraries, it gets “Get-PnPFolderItem : The attempted operation is prohibited because it exceeds the list view threshold.” error, as the Get-PnPFolderItem can’t handle large lists and libraries. So, here is the alternate script to empty a document library by deleting all files and folders in it faster with the PnP Batch method:

#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/Inventory"
$ListName = "Branding Templates"
 
Try {
    #Connect to PnP Online
    Connect-PnPOnline -Url $SiteURL -Interactive
    $List =  Get-PnPList $ListName
    $ItemCount =  $List.ItemCount
    If($ItemCount -eq 0) { Write-host "Document Library is Already Empty!" -f Yellow; Break}
 
    #Get All Items from the Library
    $global:counter = 0
    $ListItems = Get-PnPListItem -List $ListName -PageSize 500 -Fields ID -ScriptBlock { Param($items) $global:counter += $items.Count; Write-Progress -PercentComplete `
            ($global:Counter / $ItemCount * 100) -Activity "Getting Items from List" -Status "Getting Items $global:Counter of $($ItemCount)"}
    Write-Progress -Activity "Completed Getting Items from Library $($List.Title)" -Completed
 
    #Sort List Items based on Server Relative URL - Descending
    $SortedItems = $ListItems | Select-Object @{Name="ServerRelativeURL";Expression={$_.FieldValues.FileRef}}, ID | Sort-Object -Descending -Property ServerRelativeURL
     
    #Delete List Items in the Batch
    $Batch = New-PnPBatch
    ForEach ($Item in $SortedItems)
    {
        Remove-PnPListItem -List $ListName -Identity $Item.ID -Recycle -Batch $Batch
        #Write-host "Deleted Item:"$Item.ServerRelativeURL
    }
    Invoke-PnPBatch -Batch $Batch -Details
 
    Write-host -f Green "All Items in the Library deleted Successfully!"
 }
Catch {
    write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}

Wrapping up

Encountering the “List cannot be deleted while on hold or retention policy” error in SharePoint Online can be frustrating, but it’s easily resolvable by identifying the source of the hold or policy and taking appropriate action. Your solutions are: Delete all List Items First before trying to delete the list, Identifying and excluding the site from the Hold or Retention Policy, as explained above. Always ensure that actions taken align with your organization’s data governance legal and compliance obligations.

Salaudeen Rajack

Salaudeen Rajack - Information Technology Expert with Two-decades of hands-on experience, specializing in SharePoint, PowerShell, Microsoft 365, and related products. He has held various positions including SharePoint Architect, Administrator, Developer and consultant, has helped many organizations to implement and optimize SharePoint solutions. Known for his deep technical expertise, He's passionate about sharing the knowledge and insights to help others, through the real-world articles!

3 thoughts on “Fix “List cannot be deleted while on hold or retention policy” Error on SharePoint Online

Leave a Reply

Your email address will not be published. Required fields are marked *