Symptoms

Event Log:

Item 1: highest correlating event ID 26234

#26234 - The Email Router service could not process a provider work item using assembly:
Microsoft.Crm.Tools.EmailProviders.dll and class:
Microsoft.Crm.Tools.Email.Providers.SmtpPollingSendEmailProvider.
System.Threading.ThreadAbortException: Thread was being aborted.
at Microsoft.Crm.Tools.Email.Providers.CrmPollingSendEmailProvider.Run()
at Microsoft.Crm.Tools.Email.Agent.ServiceCore.ExecuteProviderWork(ObjectproviderQueueRequestObject)

Item 2: high correlation warning event ID 17972

Query execution time of 35.5 seconds exceeded the threshold of 10 seconds. Thread: 11; Database: TestOrg_MSCRM; Server:crm-sql01; Query: select 
top 5 "email0".Subject as "subject"
, "email0".Description as "description"
, "email0".PriorityCode as "prioritycode"
, "email0".ActivityId as "activityid"
, "email0".ModifiedOn as "modifiedon"
, "email0".StateCode as "statecode"
, "email0".StatusCode as "statuscode"
, "email0".DeliveryAttempts as "deliveryattempts"
, "email0".AttachmentCount as "attachmentcount"
, convert(bigint, "email0".VersionNumber) as "versionnumber"
, N'' as "safedescription"
from
Email as "email0" WITH (NOLOCK)
join ActivityParty as "activityparty1" WITH (NOLOCK) on ("email0".ActivityId = "activityparty1".ActivityId and ("activityparty1".ParticipationTypeMask = @ParticipationTypeMask0 and ("activityparty1".PartyId in (@PartyId0
, @PartyId1
, @PartyId2
, @PartyId3
, @PartyId4))))
where
("email0".StateCode = @StateCode0 and ("email0".StatusCode != @StatusCode0 or "email0".StatusCode is null) and "email0".DirectionCode = @DirectionCode0 and ("email0".DeliveryAttempts = @DeliveryAttempts0))
order by
"email0".ActualEnd asc.

Item 3: high correlation event ID 61346

#61346 - An error occurred while checking for outgoing email messages to process for SMTP: . System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: SQL timeout expired. (Fault Detail is equal to Exception details: 
ErrorCode: 0x80044151
Message: SQL timeout expired.
TimeStamp: 2012-10-05T11:54:12.3179277Z
--
Exception details:
ErrorCode: 0x80044151
Message: SQL timeout expired.
TimeStamp: 2012-10-05T11:54:12.3179277Z
--

Item 4: not a direct cause, but usually occurs as a precursor

#61346 - An error occurred while checking for outgoing email messages to process for SMTP: . System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: User does not have send-as privilege. (Fault Detail is equal to Exception details: 
ErrorCode: 0x8004480D
Message: User does not have send-as privilege.
TimeStamp: 2012-10-05T11:57:06.5096616Z
Resolution:
1. Increase the SQL execution time threshold to 60 seconds or more for the specific application database.
 

To fix a single CRM database

USE OrgName_MSCRM 
GO
EXEC sp_configure 'remote query timeout', 0
GO
RECONFIGURE
GO

To fix all CRM databases (on all CRM servers)

--View the current Setting:
select IntColumn from MSCRM_CONFIG..ServerSettingsProperties where ColumnName='LongQueryThresholdInSeconds'
--Update the Setting with a new value:
USE MSCRM_CONFIG
GO
UPDATE ServerSettingsProperties
SET IntColumn='600' where ColumnName='LongQueryThresholdInSeconds'

Source: https://learn.microsoft.com/en-us/archive/technet-wiki/12601.crm-2011-timeouts-and-limits

Explanation: by default the SQL Server’s query execution timeout is 600 seconds. Applications may override that with other values, such as 10s for MSCRM. Therefore, it’s necessary to fix these databases to make them less ‘aggressive.’
 
2. Fix the ErrorCode: 0x8004480D on any Org that exhibits such

 

Other Solutions:

Set a scheduled task on CRM servers to call this script every 30 minutes:

# processWatcher.ps1
# Version 0.0.2

# Modify these variables
$computername=$env:computername
$serviceName='MSCRMEmail'
$desiredStatus='Running'
$credential=$false # set this to false to use the default running context
$actionScript={
    param($serviceName)
    $erroractionpreference='stop'
    $emailAgentXml='C:\Program Files\Microsoft CRM Email\Service\Microsoft.Crm.Tools.EmailAgent.SystemState.xml'
    try{
        stop-service $serviceName
        Rename-Item $emailAgentXml "$emailAgentXml.old"
        Rename-Item "$emailAgentXml.bak" "$emailAgentXml.bak.old"
        start-service $serviceName
        return $true
    }catch{
        write-host $_
        return $false
    }
}
function watchProcess{
    param(
        $serviceName,
        $computername=$env:computername,
        $desiredStatus='Running',
        $action,
        $credential
        )
    function checkService($serviceName,$computername=$env:computername,$status='Running'){
        # Sanitation
        #$invalidChars=$processName.IndexOfAny([System.IO.Path]::GetInvalidFileNameChars())
        $systemInvalidChars =[Regex]::Escape(-join [System.Io.Path]::GetInvalidFileNameChars())
        $regexInvalidChars = "[$systemInvalidChars]"
        $serviceName=$serviceName -replace [regex]::Matches($serviceName, $regexInvalidChars, 'IgnoreCase').Value
        if($desiredStatus -ne 'Stopped'){
            $desiredStatus='Running'
        }
        try{
            $service=get-service -name $serviceName -ComputerName $computername|select -first 1
            if($service.Status -eq $status){
                write-host "status matches the desired state" -foregroundcolor Green
                return $true
            }elseif($null -ne $service.Status){
                write-host "status doesn`'t match the desired state" -foregroundcolor Red
                return $false
            }else{
                write-host "$serviceName was not found" -foregroundcolor Red
                return $false         
            }
        }catch{
            Write-Error $_
            return $false
        }
    }
    $serviceIsRunning=checkService $serviceName $computername $desiredStatus
    if ($serviceIsRunning){
        write-host "$serviceName is running on $computerName." -foregroundcolor Green
        return $true
    }else{
        if($session.state -eq 'Opened'){remove-pssession $session}
        do{
            $session=if($credential){
                    try{
                        New-PSSession -ComputerName $computer -Credential $credential -ea Stop
                    }catch{
                        New-PSSession -ComputerName $computer -Credential $credential -SessionOption $(new-pssessionoption -IncludePortInSPN)
                    }
                }else{
                    try{
                        New-PSSession -ComputerName $computer -ea Stop
                    }catch{
                        New-PSSession -ComputerName $computer -SessionOption $(new-pssessionoption -IncludePortInSPN)
                    }
                }
        } until ($session.state -match "Opened")
        $success=if($session -and $action -and $serviceName){
                invoke-command -Session $session -scriptblock $action -Args $serviceName
            }else{
                $false
            }
        if($session){Remove-PSSession $session}
        return $success
    }
}

watchProcess $servicename $computername $desiredStatus $actionScript $credential