XPrompt

I'm sending email through Gmail SMTP using MailKit in a .NET app, but it fails even though the firewall allows port 587, I've already setup firewall setting allow appliation outgoing thorugh smtp.gmail.com:587. ERROR LOG: MailKit.Security.SslHandshakeException -> An error occurred while attempting to establish an SSL or TLS connection. The server's SSL certificate could not be validated for the following reasons: • The server certificate has the following errors: • unable to get certificate CRL • unable to get certificate CRL • An intermediate certificate has the following errors: • unable to get certificate CRL • unable to get certificate CRL -> at MailKit.Net.Smtp.SmtpClient.PostConnectAsync(Stream stream, String host, Int32 port, SecureSocketOptions options, Boolean starttls, CancellationToken cancellationToken) at MailKit.Net.Smtp.SmtpClient.ConnectAsync(String host, Int32 port, SecureSocketOptions options, CancellationToken cancellationToken)

AI Conclusion — ChatGPT

Below is a synthesized, engineering-grade answer that distills the strongest, most accurate points from all three responses, trims risky advice, and converges on a clear resolution path.


1. Synthesized Answer (Best of All Responses)

What’s actually going wrong

This is not a Gmail SMTP or port-587 problem.

Your error:

unable to get certificate CRL

means the TLS handshake fails because the runtime cannot reach Google’s Certificate Revocation List (CRL) or OCSP endpoints during certificate validation.

Even though:

  • smtp.gmail.com:587 is allowed

  • STARTTLS is correct

…the TLS stack still needs additional outbound connectivity to verify that Google’s certificates have not been revoked.

That verification:

  • Does not go to smtp.gmail.com

  • Typically goes over HTTP (80) or HTTPS (443)

  • Targets Google PKI endpoints such as:

    • crl.pki.goog

    • ocsp.pki.goog

    • *.google.com (via CDN)

If those are blocked (very common in corporate or whitelist-only environments), MailKit correctly aborts the SSL handshake.


What this is not

  • ❌ Not an SMTP authentication issue

  • ❌ Not Gmail rejecting your credentials

  • ❌ Not a MailKit bug

  • ❌ Not fixed by “opening 587 harder”


Correct MailKit configuration (baseline check)

Ensure you are using STARTTLS, not SSL-on-connect:

csharp

`using var client = new SmtpClient();

client.Connect(
"smtp.gmail.com",
587,
SecureSocketOptions.StartTls
);

client.Authenticate("[email protected]", "app-password");
client.Send(message);
client.Disconnect(true);`

Using SslOnConnect with port 587 will fail.


Root cause (most likely, ranked)

  1. Outbound firewall / proxy blocks CRL or OCSP

    • Port 587 allowed

    • Port 80 / 443 restricted or domain-whitelisted

    • Google PKI endpoints not reachable

  2. Corporate proxy or SSL inspection

    • TLS interception

    • Missing intermediate/root CA in Windows trust store

  3. Outdated system certificate store

    • Google Trust Services (GTS) chain not fully trusted

How to prove this is the issue (high-confidence diagnostic)

Run on the affected machine:

powershell

certutil -urlfetch -verify smtp.gmail.com

If CRL or OCSP fetches timeout or fail, you have definitive proof.
At that point, this is a network policy issue, not an application bug.


2. Differences & Contradictions Between Responses

Area Gemini ChatGPT DeepSeek Synthesis
Root cause CRL blocked CRL / OCSP blocked CRL blocked ✅ All agree
Network explanation depth Medium Very strong Medium ChatGPT strongest
Disable CRL suggestion Yes Yes (test-only) Yes (recommended) ⚠️ Only for testing
Accept cert by subject/issuer ⚠️ Suggested ❌ Unsafe / misleading
Proxy discussion Light Clear Moderate ✅ Included
Production safety stance Good Strong Weak ChatGPT wins

Key contradiction to resolve

DeepSeek suggests accepting certificates by issuer/subject.
This is not cryptographically safe and can be bypassed.
It should not be used in production.


3. Clear, Actionable Recommendation (Final Verdict)

Ask your network team to allow outbound access to:

  • TCP 443 (and optionally 80)

  • *.google.com

  • crl.pki.goog

  • ocsp.pki.goog

This is the only solution that preserves full TLS security.

If Gmail works from browsers but not from your app, that’s your smoking gun: browsers already have this access.


⚠️ Short-term diagnostic only (do not ship this)

csharp

client.CheckCertificateRevocation = false;

If this immediately fixes the issue:

  • You have 100% confirmed the CRL/OCSP blockage

  • Remove this once networking is fixed


🚫 What not to do

  • Do not permanently disable certificate validation

  • Do not whitelist certificates by string matching

  • Do not assume “port 587 open = TLS works”


Bottom Line (Executive-ready summary)

The SMTP connection fails because TLS certificate revocation checks cannot reach Google’s CRL/OCSP servers. This is caused by outbound firewall or proxy restrictions, not by Gmail, MailKit, or port 587. The correct fix is to allow HTTPS access to Google PKI endpoints.

If you want, I can:

  • Draft a one-page justification for your network/security team

  • Provide a minimal allowlist tuned to your environment (Windows / Docker / K8s)

  • Help validate whether a proxy or SSL inspection device is silently breaking the chain

You were already 90% there — this is the last mile.

Gemini

It looks like you've hit a common snag with MailKit and Gmail. Even though your firewall allows traffic on port 587, the SSL Handshake is failing because MailKit is trying to verify that Google’s security certificates haven't been revoked.

The specific error unable to get certificate CRL means your application cannot reach the Certificate Revocation List (CRL) servers. These checks often happen over Port 80 (HTTP), which might still be blocked by your firewall, even if Port 587 is open.

Here is how to resolve this.


In many corporate or restricted environments, CRL checks are blocked. You can tell MailKit to skip this specific check while still maintaining an encrypted connection.

Set the CheckCertificateRevocation property to false before you call Connect:

C#

using (var client = new SmtpClient())
{
    // This stops MailKit from trying to download the CRL
    client.CheckCertificateRevocation = false;

    // Use StartTls for Port 587
    await client.ConnectAsync("smtp.gmail.com", 587, SecureSocketOptions.StartTls);

    // Note: Use an App Password if 2FA is enabled on the Gmail account
    await client.AuthenticateAsync("[email protected]", "your-app-password");
    
    await client.SendAsync(message);
    await client.DisconnectAsync(true);
}

Solution 2: Verify Firewall & Ports

If you prefer to keep CRL checks enabled for maximum security, you need to ensure your server can "talk" to the certificate authority.

  • Open Port 80: CRL and OCSP (Online Certificate Status Protocol) checks typically use standard HTTP (Port 80). If your firewall is "Whitelisting" only port 587, the handshake will time out or fail when it tries to verify the certificate.

  • Check SecureSocketOptions: Ensure you are using the correct option for the port: | Port | SecureSocketOptions | Description | | :--- | :--- | :--- | | 587 | StartTls | Starts plain text and upgrades to SSL (Standard). | | 465 | SslOnConnect | Encrypted from the very first byte. |


Solution 3: Update Trusted Root Certificates

If your host machine (where the .NET app is running) has outdated Root Certificates, it won't recognize the chain of trust for Google’s certificate.

  1. On Windows: Run Windows Update or manually update the "Trusted Root Certification Authorities."

  2. On Linux (Docker/Ubuntu): Run update-ca-certificates to ensure the local store is fresh.

Why did this happen?

When your app connects to smtp.gmail.com, Google presents a "passport" (the SSL Certificate). MailKit then tries to call the "passport office" (the Certificate Authority) to ask, "Has this specific passport been reported stolen or revoked?" If your firewall blocks that phone call to the "passport office," MailKit assumes the connection is unsafe and kills it.

Would you like me to show you how to set up a custom ServerCertificateValidationCallback if you need to bypass validation for a specific self-signed certificate instead?

ChatGPT

TL;DR:這不是「Port 587 被擋」的問題,而是「憑證驗證時抓不到 CRL(Certificate Revocation List)」。防火牆只放行 smtp.gmail.com:587 還不夠,TLS 驗證會額外連線到 Google 的憑證撤銷伺服器。

下面我用「懷疑工程師模式」幫你拆解 👇


問題本質(關鍵點)

錯誤訊息非常誠實:

unable to get certificate CRL

代表在 TLS Handshake 階段,Windows / .NET 嘗試:

  1. 驗證 Gmail SMTP 的憑證

  2. 驗證中繼憑證(Intermediate CA)

  3. 向 CA 的 CRL / OCSP 伺服器查詢「這張憑證有沒有被撤銷」

  4. 👉 但 CRL 位址被阻擋或無法連線

➡️ 結果:SSL 驗證失敗,MailKit 直接拒絕連線(這是正確、安全的行為)


為什麼「防火牆已放行 smtp.gmail.com:587」仍然會失敗?

因為 CRL / OCSP 查詢根本不是走 smtp.gmail.com

Google SMTP 憑證通常會:

  • 指向 *.google.com

  • 使用 Google Trust Services / GTS

  • CRL / OCSP 可能在:

    • http://crl.pki.goog

    • http://ocsp.pki.goog

    • 甚至透過 CDN

👉 如果你的環境是:

  • 公司防火牆

  • Proxy

  • 白名單 only

  • 出口封鎖 HTTP (80) / HTTPS (443) 的「非白名單網域」

那這個錯誤 100% 會出現。


常見高機率成因(請對號入座)

請直接檢查你中了幾個:

1️⃣ 出口防火牆只允許「特定網域」

✔️ 587 有開
❌ 443 / 80 沒全開
crl.pki.goog / ocsp.pki.goog 被擋

➡️ 最常見原因(Top 1)


2️⃣ 公司 Proxy / SSL Inspection

  • Proxy 攔 TLS

  • 替換憑證

  • 中繼 CA 沒被安裝到 Windows Trusted Root

➡️ Windows 驗證鏈直接爆炸


3️⃣ Windows 憑證存放區過舊

  • 老系統

  • Root CA / Intermediate CA 沒更新

  • 無法正確 chain 到 Google Trust Services


4️⃣ 使用錯誤的 MailKit 連線模式

例如:

csharp

client.Connect("smtp.gmail.com", 587, true); // ❌ 錯

587 必須是 STARTTLS,不是 SSL-on-connect。


正確的 MailKit 設定(請直接比對)

csharp

`using var client = new SmtpClient();

client.Connect(
"smtp.gmail.com",
587,
SecureSocketOptions.StartTls
);

client.Authenticate("[email protected]", "app-password");
client.Send(message);
client.Disconnect(true);`

⚠️ 不要用 SecureSocketOptions.SslOnConnect 搭配 587


解法優先順序(實務建議)

✅ 正解(安全、可長期用)

請網管放行以下出口:

  • TCP 443 / 80(至少到 Google PKI)

  • *.google.com

  • crl.pki.goog

  • ocsp.pki.goog

👉 這才是根治


⚠️ 可行但不優雅(僅測試)

暫時關閉憑證驗證(請只用來驗證問題來源):

csharp

client.ServerCertificateValidationCallback = (s, c, h, e) => true;

如果這樣 就能寄信
→ 恭喜,你已 100% 確認是 CRL / 憑證鏈被擋

🚨 正式環境請勿使用


🛠️ 補充檢查清單(工程師版)

在 server 上跑:

powershell

certutil -urlfetch -verify smtp.gmail.com

如果 CRL / OCSP timeout
👉 問題鐵證如山,丟給網管毫無懸念 😄


結論(給你一個「能拿去說服人的版本」)

這不是 SMTP port 問題,而是 TLS 憑證驗證時無法連線至 Google 的 CRL / OCSP 伺服器,導致 SSL Handshake 失敗。需要放行對 Google PKI 的 HTTPS/HTTP 出口流量,或修正 Proxy / 憑證信任鏈設定。

如果你願意,我也可以:

  • 幫你寫一份「丟給網管的技術說明版本」

  • 或依你的環境(Windows / Linux / Docker / K8s)給精準放行清單

這一題你其實已經快破關了,只差最後一把鑰匙 🔑

DeepSeek

This error indicates that your application is unable to validate Gmail's SSL certificate due to Certificate Revocation List (CRL) issues. This is typically a network/proxy configuration problem rather than a firewall issue with port 587.

Here are several solutions:

Solution 1: Disable CRL Checking (Quick Fix)

csharp

using (var client = new SmtpClient())
{
// Disable certificate revocation checking
client.CheckCertificateRevocation = false;

// Connect to Gmail
await client.ConnectAsync("smtp.gmail.com", 587, SecureSocketOptions.StartTls);

// Authenticate and send email
await client.AuthenticateAsync("[email protected]", "your-app-password");
// ... rest of your code

}

Solution 2: Use Custom SSL Certificate Validation

csharp

using (var client = new SmtpClient())
{
// Use custom certificate validation callback
client.ServerCertificateValidationCallback = (s, c, h, e) => {
// Add your custom validation logic here
// For testing: return true to accept all certificates (not recommended for production)
return true;
};

await client.ConnectAsync("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
// ... rest of your code

}

Solution 3: Most Secure Approach - Validate Specific Certificates

csharp

client.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {
// Accept Gmail's certificates specifically
if (certificate.Subject.Contains("google.com") ||
certificate.Subject.Contains("Gmail") ||
certificate.Issuer.Contains("Google"))
{
return true;
}
return false; // Reject other certificates
};

Solution 4: Network/Proxy Configuration Issues

If you're behind a corporate firewall or proxy:

  1. Configure your app to use system proxy settings:

csharp

// Add this before connecting
client.ProxyClient = new Socks5Client("proxy-host", 1080); // Or appropriate proxy

  1. Ensure CRL/OCSP access is allowed:

    • The firewall must also allow HTTP/HTTPS traffic to CRL distribution points

    • This usually requires allowing outbound traffic on ports 80 and 443 to various certificate authorities

  2. Update root certificates:

    • Ensure your system has updated root certificates

    • On Windows: Run certmgr.msc and ensure all root certificates are up to date

    • On Linux: Update your ca-certificates package

Solution 5: Complete Connection Example

csharp

using MailKit.Net.Smtp;
using MimeKit;

public async Task SendEmailAsync()
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Sender", "[email protected]"));
message.To.Add(new MailboxAddress("Receiver", "[email protected]"));
message.Subject = "Test Subject";

message.Body \= new TextPart("plain")
{
    Text \= "Test email body"
};

using (var client \= new SmtpClient())
{
    // Fix for CRL issue
    client.CheckCertificateRevocation \= false;
    
    // Optional: Increase timeout
    client.Timeout \= 30000;
    
    try
    {
        await client.ConnectAsync("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
        
        // Note: Use App Password if 2FA is enabled
        await client.AuthenticateAsync("[email protected]", "your-app-password");
        
        await client.SendAsync(message);
        await client.DisconnectAsync(true);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error: {ex.Message}");
    }
}

}

Additional Recommendations:

  1. Use App Passwords: If you have 2FA enabled on your Google account, generate an App Password:

    • Go to Google Account → Security → 2-Step Verification → App Passwords

    • Use this password instead of your regular password

  2. Check TLS version: Ensure your .NET runtime supports TLS 1.2+:

csharp

// Add this to your application startup
System.Net.ServicePointManager.SecurityProtocol =
SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;

  1. Temporarily disable antivirus/firewall to test if they're blocking CRL checks.

The most common solution is Solution 1 (disabling CRL checking), which is acceptable for most applications since Gmail's certificates are well-known and trusted. For production applications, consider Solution 3 for a balance between security and functionality.