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

Event ID 12025 indicates that an SSL/TLS certificate used by Exchange Server has expired, causing secure connection failures across multiple services. This is a critical error that affects user access to Outlook Web App, Exchange Admin Center, ActiveSync, and all other HTTPS-based Exchange functionality.

Certificate expiration is one of the most common causes of Exchange service outages and is entirely preventable with proper monitoring. This guide covers immediate remediation steps to restore service and long-term prevention measures to avoid future expiration issues.

Understanding Event ID 12025 Certificate Expiration

Exchange Server uses certificates for encrypting communications, authenticating servers, and establishing secure connections. When certificates expire, clients receive security warnings and some may refuse to connect entirely.

Typical Event Log Entry

Log Name: Application
Source: MSExchange Web Services
Event ID: 12025
Level: Error
Message: The certificate with thumbprint [thumbprint] used for [service] has expired on [date]. Services using this certificate may fail to establish secure connections.

The impact of certificate expiration depends on which services are assigned to the expired certificate. In most Exchange deployments, a single certificate is used for IIS, SMTP, and other services, meaning expiration affects everything.

Symptoms of Certificate Expiration

User-Facing Issues

  • Certificate warnings in web browsers
  • Outlook connectivity warnings or failures
  • Mobile devices fail to sync
  • "Your connection is not private" errors
  • Autodiscover failures
  • Cannot add new Exchange accounts

Server-Side Indicators

  • Event ID 12025 in Application log
  • Certificate shows expired in MMC
  • Test-ServiceHealth shows failures
  • Remote connectivity tests fail
  • EAC shows certificate warnings
  • SMTP TLS connections fail

Common Causes

Lack of Expiration Monitoring

Without automated monitoring, certificate expiration dates are easily forgotten. Certificates are typically valid for 1-3 years, and the renewal process is often not documented or assigned to a specific person.

Renewal Process Delays

Certificate renewal requires multiple steps: CSR generation, CA processing, certificate installation, and service restart. Any delays in this process can result in the old certificate expiring before the new one is applied.

Multiple Certificates Confusion

Organizations with multiple Exchange certificates (different domains, internal vs external) may lose track of which certificates are in use and when they expire.

Self-Signed Certificate Expiration

Default self-signed certificates created during Exchange installation have shorter validity periods and are often forgotten about, especially in test or small environments.

Diagnostic Steps

Step 1: Identify Expired Certificates

# List all Exchange certificates with expiration status
Get-ExchangeCertificate | Select-Object Subject, Thumbprint, NotAfter, Services, Status | Format-Table -AutoSize

# Find expired certificates
Get-ExchangeCertificate | Where-Object { $_.NotAfter -lt (Get-Date) } | Format-List Subject, Thumbprint, NotAfter, Services

# Find certificates expiring soon (within 30 days)
Get-ExchangeCertificate | Where-Object {
    $_.NotAfter -lt (Get-Date).AddDays(30) -and
    $_.NotAfter -gt (Get-Date)
} | Format-List Subject, Thumbprint, NotAfter, Services

Step 2: Check Which Services Use the Certificate

# Get detailed certificate information
$expiredCert = Get-ExchangeCertificate | Where-Object { $_.NotAfter -lt (Get-Date) }
$expiredCert | Format-List *

# Check services assigned to the certificate
Write-Host "Services using expired certificate:" -ForegroundColor Red
$expiredCert | ForEach-Object {
    Write-Host "Thumbprint: $($_.Thumbprint)"
    Write-Host "Services: $($_.Services)"
    Write-Host "Subject: $($_.Subject)"
}

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

Step 3: Verify Certificate Chain

# Check certificate chain status
$cert = Get-ExchangeCertificate | Where-Object { $_.Services -match "IIS" }
$certObj = Get-ChildItem "Cert:\LocalMachine\My\$($cert.Thumbprint)"

$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
$chain.Build($certObj)

Write-Host "Chain Status:" -ForegroundColor Cyan
$chain.ChainStatus | Format-Table Status, StatusInformation

Write-Host "Chain Elements:" -ForegroundColor Cyan
$chain.ChainElements | ForEach-Object {
    Write-Host "  - $($_.Certificate.Subject)"
    Write-Host "    Expires: $($_.Certificate.NotAfter)"
}

Step 4: Test Service Connectivity

# Test HTTPS connectivity to Exchange services
$urls = @(
    "https://$env:COMPUTERNAME/owa",
    "https://$env:COMPUTERNAME/ecp",
    "https://$env:COMPUTERNAME/ews/exchange.asmx",
    "https://$env:COMPUTERNAME/Microsoft-Server-ActiveSync"-Server-ActiveSync"
)

foreach ($url in $urls) {
    try {
        $response = Invoke-WebRequest -Uri $url -UseDefaultCredentials -ErrorAction Stop
        Write-Host "OK: $url" -ForegroundColor Green
    } catch {
        Write-Host "FAIL: $url - $($_.Exception.Message)"$_.Exception.Message)" -ForegroundColor Red
    }
}

# Test SMTP TLS
$smtpTest = Test-NetConnection -ComputerName $env:COMPUTERNAME -Port 25
Write-Host "SMTP Port 25: $(if($smtpTest.TcpTestSucceeded){'Open'}else{'Blocked'})"$smtpTest.TcpTestSucceeded){'Open'}else{'Blocked'})"

Quick Fix: Generate New Self-Signed Certificate

Note: Self-signed certificates cause browser warnings and are not suitable for production external access. Use this only as a temporary fix while obtaining a proper certificate from a trusted CA.

# Generate new self-signed certificate (temporary fix)
$serverFqdn = [System.Net.Dns]::GetHostByName($env:COMPUTERNAME).HostName
$domains = @($serverFqdn, "mail.contoso.com", "autodiscover.contoso.com")

$newCert = New-ExchangeCertificate -GenerateRequest:$false -SubjectName "CN=$serverFqdn" -DomainName $domains -PrivateKeyExportable $true -FriendlyName "Exchange Certificate $(Get-Date -Format 'yyyy-MM-dd')"-Format 'yyyy-MM-dd')"

Write-Host "New certificate created: $($newCert.Thumbprint)"

# Assign to services
Enable-ExchangeCertificate -Thumbprint $newCert.Thumbprint -Services IIS, SMTP, POP, IMAP -Force

# Restart IIS
iisreset /noforce

Write-Host "Certificate applied and IIS restarted" -ForegroundColor Green

Detailed Solution: Install CA-Signed Certificate

Step 1: Generate Certificate Signing Request (CSR)

# Generate CSR for public CA
$domains = @(
    "mail.contoso.com",
    "autodiscover.contoso.com",
    "owa.contoso.com"
)

$csr = New-ExchangeCertificate -GenerateRequest -SubjectName "CN=mail.contoso.com, O=Contoso Corporation, L=Seattle, S=Washington, C=US" -DomainName $domains -PrivateKeyExportable $true -KeySize 2048 -FriendlyName "Exchange Certificate 2025"

# Save CSR to file for submission to CA
$csr | Out-File "C:\Temp\ExchangeCSR.txt"

Write-Host "CSR saved to C:\Temp\ExchangeCSR.txt"
Write-Host "Submit this CSR to your certificate authority"

# View the CSR
Get-Content "C:\Temp\ExchangeCSR.txt"

Step 2: Import and Complete the Certificate

# After receiving certificate from CA, import it
$certPath = "C:\Temp\ExchangeCert.cer"  # Path to certificate file from CA

# Import the certificate (completes the request)
Import-ExchangeCertificate -FileData ([System.IO.File]::ReadAllBytes($certPath)) -FriendlyName "Exchange Certificate 2025"

# Find the new certificate
$newCert = Get-ExchangeCertificate | Where-Object { $_.FriendlyName -eq "Exchange Certificate 2025" }
Write-Host "Imported certificate: $($newCert.Thumbprint)"
Write-Host "Valid until: $($newCert.NotAfter)"

# If you have a PFX file instead (includes private key)
$pfxPath = "C:\Temp\ExchangeCert.pfx"
$pfxPassword = Read-Host "Enter PFX password" -AsSecureString
Import-ExchangeCertificate -FileData ([System.IO.File]::ReadAllBytes($pfxPath)) -Password $pfxPassword

Step 3: Assign Certificate to Services

# Get the new certificate thumbprint
$newCert = Get-ExchangeCertificate | Where-Object {
    $_.NotAfter -gt (Get-Date) -and
    $_.Subject -match "mail.contoso.com"
} | Sort-Object NotAfter -Descending | Select-Object -First 1

Write-Host "Assigning certificate: $($newCert.Thumbprint)"

# Enable certificate for Exchange services
Enable-ExchangeCertificate -Thumbprint $newCert.Thumbprint -Services IIS, SMTP, POP, IMAP -Force

# Verify assignment
Get-ExchangeCertificate -Thumbprint $newCert.Thumbprint | Format-List Subject, Thumbprint, Services, NotAfter

# Restart IIS to apply changes
iisreset /noforce

# Restart Transport for SMTP changes
Restart-Service MSExchangeTransport

Step 4: Update OAuth Configuration (If Applicable)

# For hybrid environments, update OAuth certificate if needed
$oauthCert = Get-AuthConfig | Select-Object -ExpandProperty CurrentCertificateThumbprint

# If OAuth uses a separate certificate, update it
if ($oauthCert -ne $newCert.Thumbprint) {
    Write-Host "OAuth uses different certificate. Checking if it needs update..."
    $oauth = Get-ExchangeCertificate -Thumbprint $oauthCert
    if ($oauth.NotAfter -lt (Get-Date)) {
        Write-Host "OAuth certificate also expired. Updating..."
        Set-AuthConfig -NewCertificateThumbprint $newCert.Thumbprint -NewCertificateEffectiveDate (Get-Date)
        Set-AuthConfig -PublishCertificate
    }
}

Step 5: Remove Expired Certificate

# After verifying new certificate is working, remove expired ones
$expiredCerts = Get-ExchangeCertificate | Where-Object { $_.NotAfter -lt (Get-Date) }

foreach ($cert in $expiredCerts) {
    Write-Host "Removing expired certificate: $($cert.Subject)" -ForegroundColor Yellow
    Remove-ExchangeCertificate -Thumbprint $cert.Thumbprint -Confirm:$false
}

# Verify only valid certificates remain
Get-ExchangeCertificate | Format-Table Subject, Thumbprint, NotAfter, Services -AutoSize

Verification Steps

# Comprehensive certificate health verification

Write-Host "=== Exchange Certificates ===" -ForegroundColor Cyan
Get-ExchangeCertificate | Format-Table Subject, Thumbprint, NotAfter, Services, Status -AutoSize

Write-Host ""; Write-Host "=== Certificate Validity ===" -ForegroundColor Cyan
$certs = Get-ExchangeCertificate
foreach ($cert in $certs) {
    $daysRemaining = ($cert.NotAfter - (Get-Date)).Days
    $status = if ($daysRemaining -lt 0) { "EXPIRED" } elseif ($daysRemaining -lt 30) { "EXPIRING SOON" } else { "Valid" }
    $color = if ($daysRemaining -lt 0) { "Red" } elseif ($daysRemaining -lt 30) { "Yellow" } else { "Green" }
    Write-Host "$($cert.Subject): $status ($daysRemaining days)"$status ($daysRemaining days)" -ForegroundColor $color
}

Write-Host ""; Write-Host "=== Service Connectivity ===" -ForegroundColor Cyan
$testUrls = @("https://$env:COMPUTERNAME/owa", "https://$env:COMPUTERNAME/ecp")
foreach ($url in $testUrls) {
    try {
        [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
        $response = Invoke-WebRequest -Uri $url -UseDefaultCredentials -TimeoutSec 10
        Write-Host "OK: $url (HTTP $($response.StatusCode))"$response.StatusCode))" -ForegroundColor Green
    } catch {
        Write-Host "FAIL: $url" -ForegroundColor Red
    }
}

Write-Host ""; Write-Host "=== IIS Bindings ===" -ForegroundColor Cyan
Import-Module WebAdministration
Get-ChildItem IIS:\SslBindings | Format-Table Host, Port, Thumbprint

Prevention Measures

Certificate Monitoring Script

# Schedule this script to run weekly
$warningDays = 30
$criticalDays = 7
$alertEmail = "exchange-admins@contoso.com"

$certs = Get-ExchangeCertificate
$alerts = @()

foreach ($cert in $certs) {
    $daysRemaining = ($cert.NotAfter - (Get-Date)).Days

    if ($daysRemaining -le 0) {
        $alerts += "EXPIRED: $($cert.Subject)"
    } elseif ($daysRemaining -le $criticalDays) {
        $alerts += "CRITICAL: $($cert.Subject) expires in $daysRemaining days"$daysRemaining days"
    } elseif ($daysRemaining -le $warningDays) {
        $alerts += "WARNING: $($cert.Subject) expires in $daysRemaining days"$daysRemaining days"
    }
}

if ($alerts.Count -gt 0) {
    $body = "Exchange Certificate Alert" + [Environment]::NewLine + [Environment]::NewLine
    $body += ($alerts -join [Environment]::NewLine)
    Send-MailMessage -To $alertEmail -From "monitoring@contoso.com" -Subject "Exchange Certificate Expiration Warning" -Body $body -SmtpServer "localhost"
}

Best Practices

  • Set calendar reminders 90, 60, 30 days before expiration
  • Document certificate details and renewal process
  • Use monitoring tools (SCOM, third-party) for alerts
  • Consider longer validity periods (2-3 years)
  • Maintain certificate inventory spreadsheet
  • Test renewal process annually in lab
  • Keep CA contact information readily available
  • Export certificates with private keys as backup

When to Escalate

Contact Microsoft Support or an Exchange specialist if:

  • Certificate import fails with cryptographic errors
  • Services fail to start after certificate assignment
  • Hybrid OAuth stops working after certificate renewal
  • IIS refuses to bind to the new certificate
  • Certificate chain validation fails despite valid intermediates
  • Multi-server environment has certificate sync issues

Frequently Asked Questions

Event ID 12025 is logged when an SSL/TLS certificate used by Exchange services has expired. This affects all HTTPS-based services including OWA, ECP, ActiveSync, EWS, and Outlook Anywhere. The error can also occur when the certificate chain is broken or intermediate certificates are missing.

Still Stuck? We Can Help

Our Exchange Server experts have resolved thousands of issues just like yours.

  • Remote troubleshooting in 95 minutes average
  • No upfront commitment or diagnosis fees
  • Fix-it-right guarantee with documentation
Get Expert Help
95 min
Average Response Time
24/7/365 Availability
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