没有不值得去解决的问题,也没有不值得去学习的技术!

Cloudflare 526 Troubleshooting: How acme.sh RSA/ECC Dual-Certificate Auto-Renewal Broke SSL for the English Site

Figure 2: Cloudflare explicitly returning Invalid SSL certificate

作者:

On July 28, 2026, I found that the English site en.shuijingwanwq.com was experiencing a more severe issue than before.

Previously, English articles would occasionally return 5XX errors on the first load, such as 522 or 525, but refreshing once or a few times usually restored a 200 status. Therefore, I had previously decided not to dig deeper into these intermittent errors.

But this time was different.

When accessing a newly published English article, the page consistently returned:

Plaintext
526 Invalid SSL certificate

And repeated refreshing still could not restore it.

The Cloudflare page showed:

Plaintext
Browser Working
Cloudflare Working
Host Error

At first, I wondered if this was related to the Cloudflare URL Rewrite configuration I had just done the day before.

After the final investigation, the real cause was entirely elsewhere:

The server simultaneously had two sets of acme.sh certificate records for www.shuijingwanwq.com, RSA and ECC, covering different domain scopes but both installed to the same set of Nginx production certificate files. After automatic renewal, the old RSA certificate overwrote the ECC certificate that included en.shuijingwanwq.com, ultimately causing Cloudflare Full (strict) origin verification to fail and return 526.

The entire issue can be pinpointed to:

Plaintext
2026-07-28 00:55:54 +0800

The complete troubleshooting process is documented below.


1. Symptom: From Intermittent 5XX to Persistent 526

English site address:

Plaintext
https://en.shuijingwanwq.com/

New article published that day:

Plaintext
https://en.shuijingwanwq.com/2026/07/28/20502/

Upon opening it, the browser first showed:

Plaintext
This site seems to have a problem

The server at en.shuijingwanwq.com returned an error:
526 No Reason Phrase

Cloudflare’s error page was more explicit:

Plaintext
Invalid SSL certificate
Error code 526

The page also showed:

Plaintext
Browser Working
Cloudflare Working
Host Error

This was clearly different from the previous intermittent 522 and 525 errors.

This time, refreshing multiple times still could not restore it.

Figure 1: English article persistently showing 526 error
Figure 1: English article persistently showing 526 error
Figure 2: Cloudflare explicitly returning Invalid SSL certificate
Figure 2: Cloudflare explicitly returning Invalid SSL certificate

2. Initially Suspected Yesterday’s Cloudflare Rewrite

I had just adjusted the Cloudflare URL Rewrite for the English site the day before.

The main goal was to convert something like:

Plaintext
/2026/07/14/19522/?abc=123

Into:

Plaintext
/2026/07/14/19522/

That is:

Keep the article path, only remove the query string.

Since the 526 appeared exactly the next day, my first reaction was naturally:

Could yesterday’s Cloudflare operation have affected the English site?

However, the 526 itself already provided a strong troubleshooting direction.

TLS establishment happens before HTTP Rewrite.

The entire link is roughly:

Plaintext
Browser

Cloudflare
↓ HTTPS / TLS
Origin Nginx

WordPress

Cloudflare must first successfully establish an HTTPS connection with the origin before it can continue processing the subsequent HTTP request.

Therefore, URL Rewrite itself cannot directly turn a valid certificate into an invalid one.

So instead of rolling back the Rewrite first, I directly checked the origin SSL.


3. First Check: What Certificate Did Nginx Actually Return?

Directly bypassing Cloudflare, I made a request using SNI on the server itself:

Bash
echo | openssl s_client \
    -connect 127.0.0.1:443 \
    -servername en.shuijingwanwq.com \
    2>/dev/null \
| openssl x509 \
    -noout \
    -subject \
    -issuer \
    -serial \
    -dates

Result:

Plaintext
subject=CN = www.shuijingwanwq.com
issuer=C = AT, O = ZeroSSL GmbH, CN = ZeroSSL RSA DV SSL CA 2
serial=6E24CF545939B4D5D892B22EAB842122
notBefore=Jul 27 00:00:00 2026 GMT
notAfter=Oct 25 23:59:59 2026 GMT

The certificate CN is:

Plaintext
www.shuijingwanwq.com

This in itself is not necessarily a problem, because a certificate can also cover other domains via SAN.

So I continued checking:

Bash
echo | openssl s_client \
    -connect 127.0.0.1:443 \
    -servername en.shuijingwanwq.com \
    2>/dev/null \
| openssl x509 -noout -text \
| grep -A2 "Subject Alternative Name"

Result:

Plaintext
X509v3 Subject Alternative Name:
    DNS:www.shuijingwanwq.com, DNS:shuijingwanwq.com

The problem was already very obvious.

The certificate only included:

Plaintext
www.shuijingwanwq.com
shuijingwanwq.com

But did not include:

Plaintext
en.shuijingwanwq.com

4. Strict Verification Failed, but WordPress Normal After Ignoring Certificate

To further confirm whether the problem only existed at the SSL layer, I did two tests.

First, normal certificate verification:

Bash
curl -sS \
    --max-time 20 \
    --resolve en.shuijingwanwq.com:443:127.0.0.1 \
    -o /dev/null \
    -w 'HTTP=%{http_code}\n' \
    https://en.shuijingwanwq.com/

Result:

Plaintext
HTTP=000

curl: (51) SSL: no alternative certificate subject name matches target host name 'en.shuijingwanwq.com'

Then, using -k to ignore certificate verification:

Bash
curl -k -sS \
    --max-time 20 \
    --resolve en.shuijingwanwq.com:443:127.0.0.1 \
    -o /dev/null \
    -w 'HTTP=%{http_code}\n' \
    https://en.shuijingwanwq.com/

Result:

Plaintext
HTTP=200

At this point, it could be confirmed that:

Plaintext
WordPress: Normal
PHP-FPM: At least able to process this request normally
Nginx HTTP: Normal
English site content: Normal

The real problem was in:

Plaintext
SSL hostname verification

That is:

When Cloudflare requested en.shuijingwanwq.com, the origin returned a certificate that did not include en.shuijingwanwq.com.

This perfectly explains the 526.


5. Continue Checking Nginx: Three Domains Indeed Share One Certificate

Check the Nginx configuration:

Bash
grep -RniE \
'server_name[[:space:]].*en\.shuijingwanwq\.com' \
/usr/local/nginx/conf \
/etc/nginx \
2>/dev/null

And:

Bash
nginx -T 2>&1 \
| grep -n -B20 -A40 \
'server_name[[:space:]].*en\.shuijingwanwq\.com'

Obtained:

Plaintext
listen 443 ssl http2;

ssl_certificate /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key;

server_name www.shuijingwanwq.com shuijingwanwq.com en.shuijingwanwq.com;

That is:

Plaintext
www.shuijingwanwq.com
shuijingwanwq.com
en.shuijingwanwq.com

Originally shared:

Plaintext
/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt
/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key

There is no problem with this approach itself.

The premise is that the certificate SAN must include all three domains simultaneously.

However, the current certificate only had:

Plaintext
www
root domain

Therefore, en inevitably failed.


6. Why Was It Normal Before? The Key Clue Comes from July 10

Then I remembered:

On July 10, 2026, when migrating the English site from:

Plaintext
www.shuijingwanwq.com/en/

To:

Plaintext
en.shuijingwanwq.com

I had manually re-issued the certificate.

At that time, I applied for an ECC certificate containing three domains:

Plaintext
www.shuijingwanwq.com
shuijingwanwq.com
en.shuijingwanwq.com

Therefore, the English site had been accessible normally after the migration.

The question became:

Since a certificate including en was already applied for on July 10, why did Nginx revert to an RSA certificate without en on July 28?

Continue checking acme.sh.


7. The Server Actually Had Two Sets of www Certificates Simultaneously

Execute:

Bash
grep -RHE \
    "^(Le_Domain|Le_Alt)=" \
    /root/.acme.sh/*/*.conf \
    2>/dev/null \
| grep 'shuijingwanwq\.com'

Found:

Plaintext
/root/.acme.sh/www.shuijingwanwq.com/www.shuijingwanwq.com.conf:
Le_Domain='www.shuijingwanwq.com'
Le_Alt='shuijingwanwq.com'

At the same time, there also existed:

Plaintext
/root/.acme.sh/www.shuijingwanwq.com_ecc/www.shuijingwanwq.com.conf:
Le_Domain='www.shuijingwanwq.com'
Le_Alt='shuijingwanwq.com,en.shuijingwanwq.com'

That is, the server actually contained:

RSA Certificate

Plaintext
/root/.acme.sh/www.shuijingwanwq.com/

Covering:

Plaintext
www.shuijingwanwq.com
shuijingwanwq.com

ECC Certificate

Plaintext
/root/.acme.sh/www.shuijingwanwq.com_ecc/

Covering:

Plaintext
www.shuijingwanwq.com
shuijingwanwq.com
en.shuijingwanwq.com

At this point, we were very close to the root cause.


8. The Real Problem: Two Sets of Certificates Writing to the Same Production File

Continue viewing the two sets of acme.sh configurations.

RSA:

Plaintext
Le_Keylength='2048'

Le_RealKeyPath='/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key'

Le_RealFullChainPath='/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt'

ECC:

Plaintext
Le_Keylength='ec-256'

Le_RealKeyPath='/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key'

Le_RealFullChainPath='/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt'

That is:

Although the RSA and ECC certificate sets had different SANs, both installed their automatically renewed certificates to the exact same production path.

The structure actually became:

Plaintext
RSA
www + root
        \
         \
          → www.shuijingwanwq.com.crt
          → www.shuijingwanwq.com.key
         /
        /
ECC
www + root + en

Whoever executed the automatic renewal installation last would take over the certificate used by Nginx.

This was the problem that had been hidden for half a month.


9. Evidence Closed Loop: RSA Automatic Renewal Happened Exactly at 00:55:54

Check the timestamp of the current production certificate file:

Bash
stat \
    /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt \
    /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key

Obtained:

Plaintext
Last changed:
2026-07-28 00:55:54 +0800

Then look at the RSA acme.sh configuration:

Plaintext
Le_CertCreateTimeStr='2026-07-27T16:55:54Z'

Converted to Beijing time:

Plaintext
2026-07-28 00:55:54 +0800

Exactly the same.

Then check Cron:

Bash
crontab -l | grep -i acme

Obtained:

Plaintext
51 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

That is:

Plaintext
Every day at 00:51

acme.sh runs automatically.

The entire incident chain finally formed a complete closed loop:

Plaintext
2026-07-28 00:51
acme.sh Cron starts

Detects old RSA certificate needs renewal

Re-issues RSA certificate

SAN still only has:
www.shuijingwanwq.com
shuijingwanwq.com

2026-07-28 00:55:54
Installs to production:
www.shuijingwanwq.com.crt
www.shuijingwanwq.com.key

Overwrites the original ECC three-domain certificate

Nginx loads the new RSA certificate

en.shuijingwanwq.com no longer in SAN

Cloudflare Full (strict) verification fails

526 Invalid SSL certificate

10. Why Was There No Problem After July 10?

Because on July 10, a new ECC certificate was manually applied for:

Plaintext
www
root
en

And then installed to the production location.

Therefore, from July 10 to July 27, Nginx had been normally using the ECC three-domain certificate.

But the problem was:

At that time, only the ECC certificate was added, but the original RSA automatic renewal record on the server was not handled.

The old RSA still existed:

Plaintext
www + root

And still had the installation path for the production certificate files.

So on the surface:

Plaintext
July 10: Problem solved

Actually, it was just:

Plaintext
ECC temporarily overwriting RSA

The real conflict had been lurking.

Until the next automatic renewal of the old RSA.


11. First Restore the English Site: Reinstall the ECC Three-Domain Certificate

After confirming the root cause, I did not re-issue the certificate.

Because the ECC certificate from July 10 was still valid:

Plaintext
notBefore=Jul 10 00:00:00 2026 GMT
notAfter=Oct 8 23:59:59 2026 GMT

So first back up the current production certificate:

Bash
ts="$(date +%Y%m%d-%H%M%S)"

cp -a \
    /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt \
    "/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt.bak-$ts"

cp -a \
    /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key \
    "/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key.bak-$ts"

Then reinstall ECC:

Bash
/root/.acme.sh/acme.sh --install-cert --ecc \
    -d www.shuijingwanwq.com \
    --key-file /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key \
    --fullchain-file /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt \
    --reloadcmd "nginx -t && nginx -s reload"

Output:

Plaintext
Installing key to:
/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key

Installing full chain to:
/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt

nginx: configuration file syntax is ok
nginx: configuration file test is successful

Reload success

12. Confirm Production File Has Been Restored to ECC

View the production certificate:

Bash
openssl x509 \
    -in /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt \
    -noout \
    -subject \
    -issuer \
    -serial \
    -dates \
    -ext subjectAltName

Obtained:

Plaintext
issuer=C = AT, O = ZeroSSL GmbH, CN = ZeroSSL ECC DV SSL CA 2

X509v3 Subject Alternative Name:
    DNS:www.shuijingwanwq.com
    DNS:en.shuijingwanwq.com
    DNS:shuijingwanwq.com

Continue comparing SHA-256:

Bash
sha256sum \
    /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt \
    /root/.acme.sh/www.shuijingwanwq.com/fullchain.cer \
    /root/.acme.sh/www.shuijingwanwq.com_ecc/fullchain.cer

Result:

Plaintext
66c521...  /usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt

58bab2...  /root/.acme.sh/www.shuijingwanwq.com/fullchain.cer

66c521...  /root/.acme.sh/www.shuijingwanwq.com_ecc/fullchain.cer

The production certificate was now fully consistent with the ECC.


13. Continuously Verify the Certificate Actually Provided by Nginx

To avoid misjudgment caused by the instantaneous state right after a reload, I tested 6 more times consecutively:

Bash
for i in 1 2 3 4 5 6
do
    echo | openssl s_client \
        -connect 127.0.0.1:443 \
        -servername en.shuijingwanwq.com \
        2>/dev/null \
    | openssl x509 \
        -noout \
        -issuer \
        -serial \
        -ext subjectAltName

    sleep 1
done

All 6 times returned:

Plaintext
ZeroSSL ECC DV SSL CA 2

The SAN also all included:

Plaintext
www.shuijingwanwq.com
en.shuijingwanwq.com
shuijingwanwq.com

Then continuously verify HTTPS:

Bash
for i in 1 2 3 4 5 6
do
    curl -sS \
        --max-time 20 \
        --resolve en.shuijingwanwq.com:443:127.0.0.1 \
        -o /dev/null \
        -w "第${i}次:HTTP=%{http_code} SSL_VERIFY=%{ssl_verify_result}\n" \
        https://en.shuijingwanwq.com/

    sleep 1
done

Obtained:

Plaintext
1st time: HTTP=200 SSL_VERIFY=0
2nd time: HTTP=200 SSL_VERIFY=0
3rd time: HTTP=200 SSL_VERIFY=0
4th time: HTTP=200 SSL_VERIFY=0
5th time: HTTP=200 SSL_VERIFY=0
6th time: HTTP=200 SSL_VERIFY=0

Certificate restoration complete.


14. Restoration Alone Is Not Enough: The Automatic Renewal Conflict Must Be Resolved

If I stopped here, the problem would reappear later.

Because the next renewal times for the two certificates were respectively:

ECC:

Plaintext
2026-09-07T02:56:34Z

RSA:

Plaintext
2026-09-24T16:55:54Z

If left unchanged:

Plaintext
September 7
ECC automatic renewal

Production certificate includes en

Normal

September 24
RSA automatic renewal again

Overwrites production certificate again

en disappears from SAN again

526 reappears

So the real fix could not just be:

Plaintext
Reinstall ECC once

But should eliminate:

Plaintext
RSA / ECC simultaneously controlling the same production certificate

15. Remove the Old RSA Certificate from Automatic Renewal

Before the operation, acme.sh --list showed:

Plaintext
www.shuijingwanwq.com  "2048"
SAN: shuijingwanwq.com

www.shuijingwanwq.com  "ec-256"
SAN: shuijingwanwq.com,en.shuijingwanwq.com

That is, two www records existed simultaneously.

First back up the RSA configuration directory:

Bash
ts="$(date +%Y%m%d-%H%M%S)"

cp -a \
    /root/.acme.sh/www.shuijingwanwq.com \
    "/root/.acme.sh/www.shuijingwanwq.com.backup-$ts"

This backup:

Plaintext
/root/.acme.sh/www.shuijingwanwq.com.backup-20260728-122113

Then remove the old RSA certificate from automatic renewal:

Bash
/root/.acme.sh/acme.sh --remove \
    -d www.shuijingwanwq.com

Output:

Plaintext
www.shuijingwanwq.com is removed,
the key and cert files are in
/root/.acme.sh/www.shuijingwanwq.com

You can remove them by yourself.

I did not continue to delete these historical files.

Keeping them actually makes it easier to trace this incident later.


16. Ultimately Only the ECC Three-Domain Certificate Remains

Re-execute:

Bash
/root/.acme.sh/acme.sh --list

At this point, www only had:

Plaintext
www.shuijingwanwq.com
KeyLength: ec-256
SAN:
shuijingwanwq.com,en.shuijingwanwq.com

Check the ECC automatic renewal configuration:

Plaintext
Le_Domain='www.shuijingwanwq.com'

Le_Alt='shuijingwanwq.com,en.shuijingwanwq.com'

Le_Keylength='ec-256'

Le_NextRenewTimeStr='2026-09-07T02:56:34Z'

Le_RealKeyPath='/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key'

Le_RealFullChainPath='/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt'

And the reload command had been adjusted to:

Plaintext
nginx -t && nginx -s reload

The final structure became:

Plaintext
ECC

www.shuijingwanwq.com
shuijingwanwq.com
en.shuijingwanwq.com


The only www automatic renewal record

/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.crt
/usr/local/nginx/conf/ssl/www.shuijingwanwq.com.key

The problem of two sets of certificates fighting over the production file no longer existed.


17. An HTTP Timeout Occurred Midway

After completing the certificate fix, a local test once showed:

Plaintext
HTTP=000 SSL_VERIFY=0

curl: (28) Operation timed out after 20000 milliseconds

Here:

Plaintext
SSL_VERIFY=0

Was very important.

It indicated:

SSL verification had succeeded; this was no longer the 526 certificate issue.

Therefore, I did not go back to modify the certificate, but continued to distinguish between:

Plaintext
Nginx / static resources

And:

Plaintext
WordPress dynamic requests

18. Static Files Completely Normal

Continuously test jQuery:

Bash
for i in 1 2 3
do
    curl -sS \
        --connect-timeout 5 \
        --max-time 30 \
        --resolve en.shuijingwanwq.com:443:127.0.0.1 \
        -o /dev/null \
        -w "第${i}次:HTTP=%{http_code} SSL=%{ssl_verify_result} CONNECT=%{time_connect}s TLS=%{time_appconnect}s TTFB=%{time_starttransfer}s TOTAL=%{time_total}s\n" \
        https://en.shuijingwanwq.com/wp-includes/js/jquery/jquery.min.js

    sleep 1
done

Obtained:

Plaintext
1st time: HTTP=200 SSL=0 TTFB=0.033743s
2nd time: HTTP=200 SSL=0 TTFB=0.052860s
3rd time: HTTP=200 SSL=0 TTFB=0.031175s

Indicating:

Plaintext
TCP
TLS
Nginx
Static resources

Were all normal.


19. WordPress Homepage Also Restored to 200

Continue accessing the homepage consecutively:

Plaintext
1st time:
HTTP=200
TTFB=9.024422s

2nd time:
HTTP=200
TTFB=0.540921s

3rd time:
HTTP=200
TTFB=0.020553s

The first time was relatively slow, but it subsequently dropped rapidly to:

Plaintext
0.54 seconds
0.02 seconds

Phenomenologically, this looked more like initial dynamic generation or a cache MISS gradually entering a cached state.

This was no longer the same issue as the 526, so I did not expand the troubleshooting scope.


20. Final Verification of Cloudflare from the Public Internet

Finally, returning to my local computer, no longer using:

Plaintext
--resolve ... 127.0.0.1

But actually accessing the article where the 526 originally occurred via the public internet through Cloudflare:

Bash
for i in 1 2 3
do
    echo "========== 第 ${i} 次 =========="

    curl -sS \
        --connect-timeout 10 \
        --max-time 30 \
        -o /dev/null \
        -D - \
        https://en.shuijingwanwq.com/2026/07/28/20502/ \
    | grep -Ei '^(HTTP/|server:|cf-ray:|cf-cache-status:|age:|location:)'

    sleep 2
done

Result:

Plaintext
1st time

HTTP/2 200
server: cloudflare
cf-cache-status: MISS
cf-ray: ...-LAX

Second time:

Plaintext
HTTP/2 200
server: cloudflare
age: 3
cf-cache-status: HIT
cf-ray: ...-LAX

Third time:

Plaintext
HTTP/2 200
server: cloudflare
age: 6
cf-cache-status: HIT
cf-ray: ...-LAX

These were the ultimately most important set of results.

The first request:

Plaintext
MISS

Meant Cloudflare actually performed origin retrieval.

And it was able to get:

Plaintext
HTTP/2 200

Indicating:

Plaintext
Cloudflare

Origin TLS

Certificate verification

Nginx

WordPress

Were all normal.

The subsequent two requests:

Plaintext
HIT

Indicated the page had also normally entered the Cloudflare cache.


21. Ultimate Root Cause

This issue was not:

Plaintext
Cloudflare URL Rewrite configuration error

Nor was it:

Plaintext
WordPress failure
PHP-FPM failure
Article publishing anomaly

The real root cause was:

On July 10, 2026, to migrate the English subdomain, I manually added an ECC certificate containing en.shuijingwanwq.com, but the server’s original RSA two-domain certificate retained its automatic renewal configuration, and both the RSA and ECC certificates were installed to the same set of Nginx production certificate paths.

Ultimately forming:

Plaintext
RSA
www + root
      \
       → Same crt/key
      /
ECC
www + root + en

In the early hours of July 28, the old RSA automatically renewed:

Plaintext
00:51 Cron starts

00:55:54 RSA new certificate generated and installed

Overwrites ECC

en disappears from SAN

Cloudflare Full (strict)

526 Invalid SSL certificate

22. Key Lessons Worth Remembering from This Troubleshooting

1. After Manually Re-issuing a Certificate, Check Old Automatic Renewal Records

Successfully re-issuing a certificate manually does not guarantee that future renewals will also be correct.

Especially when expanding from:

Plaintext
www + root

To:

Plaintext
www + root + en

You must confirm whether the old certificate task still exists.

Otherwise, the following is very likely to occur:

Plaintext
Normal now

Automatic renewal months later

Old configuration overwrites again

Failure suddenly returns

2. It Is Best to Have Only One “Writer” for the Same Production Certificate File

The real danger this time was not:

Plaintext
RSA and ECC existing simultaneously

But rather:

Plaintext
Both having:

Le_RealKeyPath
Le_RealFullChainPath

And the targets being exactly the same.

That is, both sets of certificates could modify the production files.

This kind of configuration is very prone to forming a hidden race condition.


3. A Certificate’s notBefore and Actual Deployment Time Are Not the Same Thing

Initially seeing:

Plaintext
notBefore=Jul 27 00:00:00 2026 GMT

It was easy to interpret as:

Plaintext
Certificate deployed on July 27

But what was truly decisive was the production file’s:

Plaintext
mtime

This time:

Plaintext
2026-07-28 00:55:54 +0800

And:

Plaintext
Le_CertCreateTimeStr

Converted to Beijing time were exactly the same.

This was what truly linked the certificate renewal and the production failure.


4. curl -k Is a Very Effective Layering Tool

There was a very crucial comparison this time:

Normal:

Plaintext
HTTP=000
certificate hostname mismatch

Ignore certificate:

Plaintext
HTTP=200

Just two requests narrowed the problem from:

Plaintext
WordPress?
PHP?
Nginx?
SSL?

Quickly down to:

Plaintext
SSL

For Cloudflare 526, this kind of test is very practical.


5. Cloudflare Full (strict) Should Not Be Disabled Just Because of a 526

One “quick way” to resolve a 526 might be to lower the SSL verification strength.

But this actually just bypasses the problem.

If I had directly modified the Cloudflare SSL mode this time, the page might have temporarily recovered, but:

Plaintext
Origin still serving the wrong certificate
RSA / ECC conflict still exists
Next renewal still uncontrollable

What should truly be fixed is:

Plaintext
The certificate itself
+
The automatic renewal lifecycle

Therefore, Cloudflare Full (strict) was not modified this time.


23. Regarding the Previous Intermittent 522 / 525

Before this persistent 526, the English site had actually occasionally experienced:

Plaintext
522
525

And often:

Plaintext
First attempt fails
Second refresh normal

During this troubleshooting, I once wondered if there was a direct connection between the two.

However, what can be clearly confirmed now is only:

The direct cause of the persistent 526 on July 28 was the RSA two-domain certificate overwriting the ECC three-domain certificate.

As to whether the previous intermittent 522 / 525 involved other link issues, I have not expanded the investigation for now.

Therefore, I temporarily maintain the original plan:

Do not analyze the intermittent 522 / 525 for now.

If they stably reproduce later, I will troubleshoot them separately to avoid mixing the two issues together.


24. Final Result

After the fix was completed:

Plaintext
Origin certificate:
ZeroSSL ECC DV SSL CA 2

SAN:

Plaintext
www.shuijingwanwq.com
shuijingwanwq.com
en.shuijingwanwq.com

Local origin:

Plaintext
HTTP=200
SSL_VERIFY=0

Public internet Cloudflare:

Plaintext
MISS → HTTP/2 200
HIT  → HTTP/2 200
HIT  → HTTP/2 200

The old RSA automatic renewal record in acme.sh has been removed.

Now, the only one responsible for the production environment is:

Plaintext
www.shuijingwanwq.com
ec-256

SAN:
shuijingwanwq.com
en.shuijingwanwq.com

At this point, this Cloudflare 526 incident was officially resolved.


Summary

The most interesting aspect of this incident is that:

The real problem was not a newly created configuration error on that day, but a certificate lifecycle conflict left behind half a month ago, which only truly erupted when the old certificate automatically renewed.

When migrating the English subdomain on July 10, I did correctly issue and deploy the ECC certificate containing en.shuijingwanwq.com.

Thus, the English site was able to run normally for over ten consecutive days.

But the server’s original RSA certificate did not disappear.

It still:

Plaintext
Automatically renewed
+
Had the same production installation path

So, in the early hours of July 28:

Plaintext
A completely "successful" automatic renewal

Instead caused a production failure.

This made me realize once again that:

The most dangerous situation with automated configurations is not necessarily a “task execution failure,” but rather an “old task continuing to execute successfully.”

Because from acme.sh’s perspective:

Plaintext
Certificate application successful
File installation successful
Nginx restart successful

There was no anomaly in the entire process.

The real problem was simply:

Plaintext
It successfully installed an old certificate that was "no longer suitable for the current architecture."

The final solution was not just to redeploy a correct certificate once, but to remove the old RSA automatic renewal task, leaving only the ECC three-domain certificate with control over the production certificate files.

Only then was this fix truly complete.

系列导航

需要长期技术维护或远程问题排查?

我是拥有 15+ 年经验的 PHP / Go 后端工程师,长期关注已有系统维护、Bug 修复、性能优化、服务器排查、WordPress 网站维护和小功能迭代。

如果你的项目遇到以下情况,可以先从一次小问题排查开始合作:

  • ✅ PHP / Laravel / Yii2 老项目无人维护
  • ✅ Go / Gin 后端接口需要排查或优化
  • ✅ WordPress 网站访问慢、报错或插件冲突
  • ✅ Nginx / MySQL / Redis / Linux 服务器异常
  • ✅ CDN / Cloudflare / DNS / HTTPS 配置问题
  • ✅ 需要长期远程技术支持或兼职维护

更多介绍请查看:关于我 & 合作

微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理