Event ID 36874: Certificate Trust Chain Error

Complete troubleshooting guide for Schannel Event ID 36874 certificate trust chain validation failures in Exchange Server. Learn how to diagnose missing intermediate certificates, expired root CAs, and SSL/TLS handshake failures affecting secure communications.

Medha Cloud
Medha Cloud Exchange Server Team
Exchange Database Recovery Team8 min read

Table of Contents

Reading Progress
0 of 10

Error Overview

Event ID 36874 from Schannel indicates a certificate trust chain validation failure during SSL/TLS handshake operations. This critical security error occurs when Windows cannot verify the complete chain of trust from your Exchange server's SSL certificate to a trusted root Certificate Authority.

Trust chain errors prevent secure connections to Exchange services, affecting Outlook clients, ActiveSync mobile devices, OWA users, and server-to-server communications. The impact extends to hybrid deployments where certificate validation is essential for Azure AD and Office 365 integration.

Event Log Entry:

Source: Schannel | Event ID: 36874 | Level: Error
"A TLS 1.2 connection request was received from a remote client application, but none of the cipher suites supported by the client application are supported by the server. The TLS connection request has failed."

Symptoms & Detection

Client-Side Symptoms

  • Outlook displays "The security certificate was issued by a company you have not chosen to trust"
  • Mobile devices fail to configure Exchange ActiveSync with certificate errors
  • OWA shows SSL certificate warning pages in browsers
  • Autodiscover failures with certificate validation errors
  • Third-party applications unable to connect via EWS

Server-Side Indicators

  • Schannel Event ID 36874 in System event log
  • Event ID 36888: "A fatal alert was generated and sent to the remote endpoint"
  • Hybrid Configuration Wizard fails with certificate errors
  • Federation trust validation failures
  • Mail flow issues with TLS-encrypted connections to partner organizations

Common Causes

1. Missing Intermediate Certificates

The most common cause - intermediate CA certificates are not installed on the Exchange server. Public CAs issue certificates signed by intermediates, not directly by root CAs. Without the complete chain, clients cannot validate the certificate back to the root CA.

2. Expired Root or Intermediate CA

Root CA certificates or intermediate certificates in the chain have expired. Even if your server certificate is valid, an expired certificate anywhere in the chain breaks validation. This commonly occurs when CAs update their certificate hierarchy.

3. Untrusted Root Certificate Authority

The root CA is not present in the Windows Trusted Root Certification Authorities store. This affects internal PKI deployments where the enterprise root CA hasn't been distributed to all clients, or when using certificates from lesser-known CAs.

4. Certificate Chain Order Issues

Certificates are installed in the wrong order or bound incorrectly. IIS and Exchange require the certificate chain to be properly ordered from server certificate through intermediates. Incorrect import procedures can scramble the chain order.

5. Revoked Certificates in Chain

A certificate in the chain has been revoked by the issuing CA. Certificate Revocation List (CRL) or OCSP checks indicate the certificate is no longer trusted, causing validation failure even when the chain structure is correct.

Diagnosis Steps

Step 1: Check Schannel Events

Review Schannel errors for detailed certificate chain information:

# Get Schannel certificate errors
Get-WinEvent -FilterHashtable @{
    LogName='System'
    ProviderName='Schannel'
    ID=36874,36888,36887
} -MaxEvents 50 | Format-List TimeCreated, Message

# Check for additional certificate errors
Get-WinEvent -FilterHashtable @{
    LogName='System'
    Level=2  # Error
} -MaxEvents 100 | Where-Object {
    $_.Message -like "*certificate*" -or
    $_.Message -like "*trust*" -or
    $_.Message -like "*chain*"
} | Format-Table TimeCreated, Id, Message -Wrap

Step 2: Analyze Certificate Chain

Examine the complete certificate chain on Exchange:

# Get Exchange certificates and their chain status
Get-ExchangeCertificate | ForEach-Object {
    $cert = $_
    $chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
    $chain.ChainPolicy.RevocationMode = "Online"
    $chain.ChainPolicy.RevocationFlag = "EntireChain"

    $chainBuilt = $chain.Build($cert)

    [PSCustomObject]@{
        Thumbprint = $cert.Thumbprint
        Subject = $cert.Subject
        NotAfter = $cert.NotAfter
        ChainValid = $chainBuilt
        ChainStatus = ($chain.ChainStatus | ForEach-Object { $_.StatusInformation }) -join "; "
        ChainLength = $chain.ChainElements.Count
    }
} | Format-List

# Detailed chain element inspection
$cert = Get-ExchangeCertificate | Where-Object { $_.Services -match 'IIS' }
$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
$chain.Build($cert) | Out-Null

Write-Host "Certificate Chain Elements:" -ForegroundColor Cyan
for ($i = 0; $i -lt $chain.ChainElements.Count; $i++) {
    $element = $chain.ChainElements[$i]
    Write-Host "`n[$i] $($element.Certificate.Subject)"$element.Certificate.Subject)" -ForegroundColor Yellow
    Write-Host "    Issuer: $($element.Certificate.Issuer)"
    Write-Host "    Valid: $($element.Certificate.NotBefore) to $($element.Certificate.NotAfter)"$element.Certificate.NotAfter)"
    Write-Host "    Thumbprint: $($element.Certificate.Thumbprint)"
}

Step 3: Test SSL Connection Externally

Use OpenSSL to verify the presented certificate chain:

# Using OpenSSL (if installed) to check certificate chain
# Install OpenSSL or use from Git installation
$opensslPath = "C:\Program Files\Git\usr\bin\openssl.exe"

# Test HTTPS connection
& $opensslPath s_client -connect mail.contoso.com:443 -showcerts 2>&1

# Test SMTP with STARTTLS
& $opensslPath s_client -connect mail.contoso.com:25 -starttls smtp -showcerts 2>&1

# PowerShell native approach to test SSL
$tcpClient = New-Object System.Net.Sockets.TcpClient
$tcpClient.Connect("mail.contoso.com", 443)
$sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream(), $false, {
    param($sender, $certificate, $chain, $sslPolicyErrors)

    Write-Host "SSL Policy Errors: $sslPolicyErrors" -ForegroundColor Yellow
    Write-Host "Certificate Subject: $($certificate.Subject)"
    Write-Host "Certificate Issuer: $($certificate.Issuer)"
    Write-Host "Valid From: $($certificate.GetEffectiveDateString())"
    Write-Host "Valid To: $($certificate.GetExpirationDateString())"

    Write-Host "`nChain Elements:" -ForegroundColor Cyan
    foreach ($element in $chain.ChainElements) {
        Write-Host "  - $($element.Certificate.Subject)"
    }

    Write-Host "`nChain Status:" -ForegroundColor Cyan
    foreach ($status in $chain.ChainStatus) {
        Write-Host "  - $($status.Status): $($status.StatusInformation)"$status.StatusInformation)"
    }

    return $true  # Accept for testing purposes
})

try {
    $sslStream.AuthenticateAsClient("mail.contoso.com")
} finally {
    $sslStream.Close()
    $tcpClient.Close()
}

Step 4: Verify Certificate Stores

Check intermediate and root CA certificate stores:

# Check Intermediate Certification Authorities store
Write-Host "Intermediate CA Certificates:" -ForegroundColor Cyan
Get-ChildItem Cert:\LocalMachine\CA |
    Select-Object Subject, Issuer, NotAfter, Thumbprint |
    Format-Table -Wrap

# Check Trusted Root Certification Authorities
Write-Host "`nTrusted Root CAs:" -ForegroundColor Cyan
Get-ChildItem Cert:\LocalMachine\Root |
    Where-Object { $_.NotAfter -lt (Get-Date).AddDays(90) } |
    Select-Object Subject, NotAfter |
    Sort-Object NotAfter |
    Format-Table -AutoSize

# Find certificates about to expire in chain stores
Write-Host "`nExpiring Chain Certificates (next 90 days):" -ForegroundColor Yellow
@('Root', 'CA') | ForEach-Object {
    $storeName = $_
    Get-ChildItem "Cert:\LocalMachine\$storeName" |
        Where-Object { $_.NotAfter -lt (Get-Date).AddDays(90) -and $_.NotAfter -gt (Get-Date) } |
        Select-Object @{N='Store';E={$storeName}}, Subject, NotAfter
} | Format-Table -AutoSize

Quick Fix

Most certificate trust chain errors are resolved by installing missing intermediate certificates:

# Download and install intermediate certificates from your CA
# Example for DigiCert - adjust URL for your certificate provider

# 1. Download intermediate certificate
$intermediateUrl = "https://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt"
$intermediatePath = "$env:TEMP\intermediate.crt"
Invoke-WebRequest -Uri $intermediateUrl -OutFile $intermediatePath

# 2. Import to Intermediate Certification Authorities store
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($intermediatePath)
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store("CA", "LocalMachine")
$store.Open("ReadWrite")
$store.Add($cert)
$store.Close()

Write-Host "Intermediate certificate installed successfully" -ForegroundColor Green

# 3. Verify chain is now complete
$exchangeCert = Get-ExchangeCertificate | Where-Object { $_.Services -match 'IIS' }
$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
$result = $chain.Build($exchangeCert)
Write-Host "Chain validation result: $result" -ForegroundColor $(if($result){'Green'}else{'Red'})

# 4. Reset IIS to apply changes
iisreset /noforce

💡 Tip: Contact your certificate provider for the correct intermediate certificate bundle. Many CAs provide a "certificate chain" or "CA bundle" file that includes all required intermediates.

Detailed Solutions

Solution 1: Complete Chain Installation

Properly import the entire certificate chain with all intermediate certificates:

# Method 1: Import PFX with complete chain
# Ensure your PFX file includes all certificates in the chain

$pfxPath = "C:\Certificates\exchange-cert-with-chain.pfx"-with-chain.pfx"
$pfxPassword = Read-Host "Enter PFX password" -AsSecureString

# Import with chain preservation
$importParams = @{
    FilePath = $pfxPath
    Password = $pfxPassword
    PrivateKeyExportable = $true
}
Import-ExchangeCertificate @importParams

# Method 2: Manually install each certificate in chain

# Install Root CA (if internal PKI)
$rootCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$rootCert.Import("C:\Certificates\RootCA.cer")
$rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("Root", "LocalMachine")
$rootStore.Open("ReadWrite")
$rootStore.Add($rootCert)
$rootStore.Close()

# Install Intermediate CA(s)
$intermediateCerts = @(
    "C:\Certificates\IntermediateCA1.cer",
    "C:\Certificates\IntermediateCA2.cer"
)

$caStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("CA", "LocalMachine")
$caStore.Open("ReadWrite")

foreach ($certPath in $intermediateCerts) {
    $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
    $cert.Import($certPath)
    $caStore.Add($cert)
    Write-Host "Installed: $($cert.Subject)" -ForegroundColor Green
}
$caStore.Close()

# Verify complete chain
Write-Host "`nVerifying certificate chain..." -ForegroundColor Cyan
$exchangeCert = Get-ExchangeCertificate | Where-Object { $_.Services -match 'IIS' }
certutil -verify -urlfetch $exchangeCert.Thumbprint

Solution 2: Update Expired CA Certificates

Replace expired root or intermediate CA certificates with updated versions:

# Find expired certificates in chain stores
Write-Host "Checking for expired chain certificates..." -ForegroundColor Cyan

$expiredCerts = @()
@('Root', 'CA') | ForEach-Object {
    $storeName = $_
    Get-ChildItem "Cert:\LocalMachine\$storeName" |
        Where-Object { $_.NotAfter -lt (Get-Date) } |
        ForEach-Object {
            $expiredCerts += [PSCustomObject]@{
                Store = $storeName
                Subject = $_.Subject
                Expired = $_.NotAfter
                Thumbprint = $_.Thumbprint
            }
        }
}

$expiredCerts | Format-Table -AutoSize

# Update Windows root certificates via Windows Update
# This downloads the latest root certificate list from Microsoft
certutil -generateSSTFromWU roots.sst
certutil -addstore -f Root roots.sst
Remove-Item roots.sst

# For internal PKI - get updated CA certificates from your PKI team
# Remove old CA certificate
$oldThumbprint = "OLD_CERTIFICATE_THUMBPRINT"
$caStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("CA", "LocalMachine")
$caStore.Open("ReadWrite")
$oldCert = $caStore.Certificates | Where-Object { $_.Thumbprint -eq $oldThumbprint }
if ($oldCert) {
    $caStore.Remove($oldCert)
    Write-Host "Removed expired certificate: $($oldCert.Subject)" -ForegroundColor Yellow
}
$caStore.Close()

# Import new CA certificate
$newCaPath = "C:\Certificates\NewIntermediateCA.cer"
certutil -addstore CA $newCaPath

Solution 3: Fix Certificate Binding Order

Correct certificate binding issues in IIS and Exchange:

# Check current IIS SSL bindings
Import-Module WebAdministration
Get-ChildItem IIS:\SslBindings | Format-Table -AutoSize

# Remove problematic binding
$bindingIP = "0.0.0.0"0.0.0"
$bindingPort = 443
Remove-Item "IIS:\SslBindings\$bindingIP!$bindingPort"$bindingPort" -ErrorAction SilentlyContinue

# Get the correct certificate with valid chain
$validCert = Get-ExchangeCertificate | Where-Object {
    $_.Services -match 'IIS' -and
    $_.NotAfter -gt (Get-Date)
} | Select-Object -First 1

# Rebind certificate to IIS
$validCert | Enable-ExchangeCertificate -Services IIS -Force

# Verify binding
Write-Host "`nUpdated SSL Bindings:" -ForegroundColor Cyan
Get-ChildItem IIS:\SslBindings | Format-Table

# Check Exchange virtual directory certificates
Get-ExchangeCertificate | Where-Object { $_.Services -ne 'None' } |
    Select-Object Thumbprint, Services, Subject, NotAfter |
    Format-Table -AutoSize

# Reset IIS with certificate update
iisreset /noforce

# Re-enable certificate for all Exchange services
$thumbprint = $validCert.Thumbprint
Enable-ExchangeCertificate -Thumbprint $thumbprint -Services IIS,SMTP,POP,IMAP -Force

Solution 4: Configure Certificate Revocation Checking

Address CRL and OCSP accessibility issues causing chain validation failures:

# Check CRL distribution points accessibility
$cert = Get-ExchangeCertificate | Where-Object { $_.Services -match 'IIS' }

# Extract CRL URLs from certificate
$crlUrls = $cert.Extensions | Where-Object {
    $_.Oid.FriendlyName -eq "CRL Distribution Points"
} | ForEach-Object {
    $_.Format($true)
}
Write-Host "CRL Distribution Points:" -ForegroundColor Cyan
$crlUrls

# Test CRL accessibility
$crlTestUrls = @(
    "http://crl3.digicert.com/sha2-ev-server-g2.crl"-server-g2.crl",
    "http://crl4.digicert.com/sha2-ev-server-g2.crl"-server-g2.crl"
)

foreach ($url in $crlTestUrls) {
    try {
        $response = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 10
        Write-Host "✓ CRL accessible: $url" -ForegroundColor Green
    } catch {
        Write-Host "✗ CRL not accessible: $url" -ForegroundColor Red
        Write-Host "  Error: $($_.Exception.Message)" -ForegroundColor Yellow
    }
}

# If CRL is blocked, configure proxy or firewall exception
# Check proxy settings
netsh winhttp show proxy

# Configure proxy for certificate validation (if needed)
# netsh winhttp set proxy proxy-server="proxy.contoso.com:8080""proxy.contoso.com:8080"

# Alternative: Configure registry to use cached CRL
# WARNING: This reduces security - use only if CRL access is impossible
$regPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CertDllCreateCertificateChainEngine\Config"
# Set-ItemProperty -Path $regPath -Name "ChainUrlRetrievalTimeoutMilliseconds" -Value 15000-Path $regPath -Name "ChainUrlRetrievalTimeoutMilliseconds" -Value 15000

# Verify certificate revocation status
certutil -verify -urlfetch $cert.Thumbprint

Solution 5: Internal PKI Chain Distribution

For internal PKI environments, ensure proper certificate distribution via Group Policy:

# Export certificates for Group Policy distribution
# Run on CA server or server with chain certificates

# Export Root CA
$rootCert = Get-ChildItem Cert:\LocalMachine\Root |
    Where-Object { $_.Subject -like "*Contoso Root CA*" }
Export-Certificate -Cert $rootCert -FilePath "C:\GPO\RootCA.cer"

# Export Intermediate CA(s)
$intermediateCerts = Get-ChildItem Cert:\LocalMachine\CA |
    Where-Object { $_.Subject -like "*Contoso*" }
$i = 1
foreach ($cert in $intermediateCerts) {
    Export-Certificate -Cert $cert -FilePath "C:\GPO\IntermediateCA$i.cer"
    $i++
}

# Create GPO for certificate distribution (run on DC)
# Using Group Policy Management PowerShell module
Import-Module GroupPolicy

$gpoName = "Certificate Distribution - Exchange"
New-GPO -Name $gpoName

# Link to appropriate OU
$ouPath = "OU=Servers,DC=contoso,DC=com"
New-GPLink -Name $gpoName -Target $ouPath

Write-Host @"
GPO Created: $gpoName

Manual steps to complete in Group Policy Management:
1. Edit the GPO
2. Navigate to: Computer Configuration > Policies > Windows Settings >
   Security Settings > Public Key Policies
3. Import Root CA to: Trusted Root Certification Authorities
4. Import Intermediate CA(s) to: Intermediate Certification Authorities
5. Run 'gpupdate /force' on Exchange servers
"1. Edit the GPO
2. Navigate to: Computer Configuration > Policies > Windows Settings >
   Security Settings > Public Key Policies
3. Import Root CA to: Trusted Root Certification Authorities
4. Import Intermediate CA(s) to: Intermediate Certification Authorities
5. Run 'gpupdate /force' on Exchange servers
"@ -ForegroundColor Yellow

# Force Group Policy update on Exchange server
gpupdate /force

# Verify certificates were distributed
Write-Host "`nVerifying certificate stores after GPO..." -ForegroundColor Cyan
Get-ChildItem Cert:\LocalMachine\Root |
    Where-Object { $_.Subject -like "*Contoso*" } |
    Select-Object Subject, Thumbprint

Get-ChildItem Cert:\LocalMachine\CA |
    Where-Object { $_.Subject -like "*Contoso*" } |
    Select-Object Subject, Thumbprint

Verification Steps

Verify the certificate trust chain is properly configured:

# Comprehensive certificate chain verification
Write-Host "=== Certificate Chain Verification ===" -ForegroundColor Cyan

# 1. Verify Exchange certificate chain
$cert = Get-ExchangeCertificate | Where-Object { $_.Services -match 'IIS' }
$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
$chain.ChainPolicy.RevocationMode = "Online"
$chain.ChainPolicy.RevocationFlag = "EntireChain"
$chain.ChainPolicy.VerificationFlags = "NoFlag"

$chainValid = $chain.Build($cert)

Write-Host "`n1. Chain Validation: $(if($chainValid){'PASSED'}else{'FAILED'})" -ForegroundColor $(if($chainValid){'Green'}else{'Red'})

if (-not $chainValid) {
    Write-Host "   Chain Status Issues:" -ForegroundColor Yellow
    foreach ($status in $chain.ChainStatus) {
        Write-Host "   - $($status.Status): $($status.StatusInformation)"$status.StatusInformation)"
    }
}

# 2. Display complete chain
Write-Host "`n2. Certificate Chain Hierarchy:" -ForegroundColor Cyan
for ($i = 0; $i -lt $chain.ChainElements.Count; $i++) {
    $element = $chain.ChainElements[$i]
    $prefix = "  " * $i + "└─"
    Write-Host "$prefix $($element.Certificate.Subject)"$element.Certificate.Subject)"
    Write-Host "$("  " * ($i+1))  Valid: $($element.Certificate.NotBefore.ToString('yyyy-MM-dd')) to $($element.Certificate.NotAfter.ToString('yyyy-MM-dd'))"1))  Valid: $($element.Certificate.NotBefore.ToString('yyyy-MM-dd')) to $($element.Certificate.NotAfter.ToString('yyyy-MM-dd'))"
}

# 3. Test SSL connectivity to all Exchange endpoints
Write-Host "`n3. SSL Endpoint Testing:" -ForegroundColor Cyan
$endpoints = @(
    @{Name="OWA"; Port=443; Path="/owa"},
    @{Name="ECP"; Port=443; Path="/ecp"},
    @{Name="Autodiscover"; Port=443; Path="/autodiscover"},
    @{Name="SMTP"; Port=25; Path=$null}
)

$serverFQDN = [System.Net.Dns]::GetHostByName($env:COMPUTERNAME).HostName

foreach ($endpoint in $endpoints) {
    try {
        if ($endpoint.Path) {
            $uri = "https://$serverFQDN$($endpoint.Path)"$endpoint.Path)"
            $request = [System.Net.HttpWebRequest]::Create($uri)
            $request.AllowAutoRedirect = $false
            $request.Timeout = 10000
            $response = $request.GetResponse()
            $response.Close()
            Write-Host "   ✓ $($endpoint.Name) (Port $($endpoint.Port)): SSL OK"$endpoint.Port)): SSL OK" -ForegroundColor Green
        } else {
            # SMTP test
            $tcpClient = New-Object System.Net.Sockets.TcpClient
            $tcpClient.Connect($serverFQDN, $endpoint.Port)
            $tcpClient.Close()
            Write-Host "   ✓ $($endpoint.Name) (Port $($endpoint.Port)): Reachable"$endpoint.Port)): Reachable" -ForegroundColor Green
        }
    } catch {
        Write-Host "   ✗ $($endpoint.Name) (Port $($endpoint.Port)): $($_.Exception.Message)"$endpoint.Port)): $($_.Exception.Message)" -ForegroundColor Red
    }
}

# 4. Verify no Schannel errors in last hour
Write-Host "`n4. Recent Schannel Errors:" -ForegroundColor Cyan
$schannelErrors = Get-WinEvent -FilterHashtable @{
    LogName='System'
    ProviderName='Schannel'
    Level=2
    StartTime=(Get-Date).AddHours(-1)
} -ErrorAction SilentlyContinue

if ($schannelErrors) {
    Write-Host "   ✗ Found $($schannelErrors.Count) Schannel errors in the last hour" -ForegroundColor Red
} else {
    Write-Host "   ✓ No Schannel errors in the last hour" -ForegroundColor Green
}

# 5. External validation (requires internet)
Write-Host "`n5. External Chain Validation:" -ForegroundColor Cyan
$publicFQDN = "mail.contoso.com"  # Replace with your public FQDN
try {
    $result = Invoke-WebRequest -Uri "https://www.sslshopper.com/ssl-checker.html#hostname=$publicFQDN"#hostname=$publicFQDN" -UseBasicParsing -TimeoutSec 5-UseBasicParsing -TimeoutSec 5
    Write-Host "   Check your certificate at: https://www.sslshopper.com/ssl-checker.html#hostname=$publicFQDN"#hostname=$publicFQDN"
} catch {
    Write-Host "   Manual check recommended: https://www.sslshopper.com/ssl-checker.html"
}

Write-Host "`n=== Verification Complete ===" -ForegroundColor Cyan

Prevention Measures

Certificate Management

  • Always request certificates with complete chain from CA
  • Import PFX files that include intermediate certificates
  • Document your CA's intermediate certificate requirements
  • Maintain current intermediate certificate bundle from CA

Monitoring Strategy

  • Set up automated certificate expiration monitoring
  • Monitor Schannel Event ID 36874 and 36888 alerts
  • Subscribe to CA notifications for intermediate updates
  • Implement SSL/TLS monitoring for all endpoints

Renewal Procedures

  • Renew certificates 30+ days before expiration
  • Verify new certificates have complete chain before deployment
  • Test in staging environment before production
  • Document certificate installation procedures

Network Configuration

  • Ensure CRL and OCSP endpoints are accessible
  • Configure firewall rules for certificate validation
  • Set up proper proxy configuration for HTTPS validation
  • Keep Windows root certificate updates enabled

Automated Chain Monitoring Script

# Scheduled task script for certificate chain monitoring
# Run weekly to detect chain issues before they cause outages

$alertEmail = "exchange-admins@contoso.com"
$smtpServer = "smtp.contoso.com"
$warningDays = 60

$issues = @()

# Check all Exchange certificates
Get-ExchangeCertificate | ForEach-Object {
    $cert = $_

    # Check expiration
    $daysToExpire = ($cert.NotAfter - (Get-Date)).Days
    if ($daysToExpire -lt $warningDays) {
        $issues += "Certificate '$($cert.Subject)' expires in $daysToExpire days"$daysToExpire days"
    }

    # Check chain validity
    $chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
    $chain.ChainPolicy.RevocationMode = "Online"
    if (-not $chain.Build($cert)) {
        $statusMessages = ($chain.ChainStatus | ForEach-Object { $_.StatusInformation }) -join "; "
        $issues += "Certificate '$($cert.Subject)' has chain issues: $statusMessages"$statusMessages"
    }
}

# Check intermediate CA expiration
Get-ChildItem Cert:\LocalMachine\CA | ForEach-Object {
    $daysToExpire = ($_.NotAfter - (Get-Date)).Days
    if ($daysToExpire -lt $warningDays -and $daysToExpire -gt 0) {
        $issues += "Intermediate CA '$($_.Subject)' expires in $daysToExpire days"$daysToExpire days"
    }
}

# Send alert if issues found
if ($issues.Count -gt 0) {
    $body = "Certificate Chain Monitoring Alert`n`n"
    $body += "The following issues were detected:`n`n"
    $body += ($issues | ForEach-Object { "• $_" }) -join "`n"

    Send-MailMessage -From "monitoring@contoso.com" -To $alertEmail -Subject "Exchange Certificate Chain Alert" -Body $body -SmtpServer $smtpServer
}

When to Escalate

Escalate to senior administrators or Microsoft Support when:

  • Chain validation fails despite having all certificates installed correctly
  • CRL or OCSP endpoints are unreachable due to network restrictions you cannot modify
  • Internal PKI issues require coordination with your enterprise CA team
  • Hybrid deployment certificate issues affecting Office 365 integration
  • Federation trust or organization relationships broken due to certificate errors
  • Certificate provider has revoked or replaced intermediate certificates unexpectedly

Need Immediate Expert Assistance?

Certificate trust chain errors can completely block secure communications. Our Exchange Server specialists provide rapid resolution for complex certificate chain issues.

Frequently Asked Questions

A certificate trust chain is the hierarchical path from your SSL certificate through intermediate certificates to a trusted root CA. Each certificate in the chain is signed by the one above it. If any link is missing, expired, or untrusted, the entire chain fails validation, causing Schannel Event ID 36874 errors and SSL/TLS connection failures.

Can't Resolve This Error?

Exchange errors can cause data loss or extended downtime. Our specialists are available 24/7 to help.

Emergency help - Chat with us
Medha Cloud

Medha Cloud Exchange Server Team

Microsoft Exchange Specialists

Our Exchange Server specialists have 15+ years of combined experience managing enterprise email environments. We provide 24/7 support, emergency troubleshooting, and ongoing administration for businesses worldwide.

15+ Years ExperienceMicrosoft Certified99.7% Success Rate24/7 Support