What the check looks at
A2 compares two connections: the one from the visitor to Cloudflare, and the one from Cloudflare to your server. For the first it reads the CF-Visitor header Cloudflare adds to each request, which says whether the visitor used https. For the second it reads the port your server received the request on (SERVER_PORT, with REQUEST_SCHEME): 443 counts as https, and 80, 8080, 8000 and 8008 count as plain http. It deliberately ignores $_SERVER['HTTPS'], because plugins and wp-config.php often set it to on.
The request it reads is a test request your server sends to its own site over https, or your own visit to the admin. When the request arrived over plain http, the plugin also tries to open a TLS connection to port 443 on your server, to learn whether https is available there at all.
Like every request Edge Doctor sends, these go only to the hosts of your Site Address and WordPress Address (home_url() and site_url()). An address WordPress gives on another host, such as a single sign on page, is never requested.
Results and what they mean
| Result | What it means |
|---|---|
| PassedConfidence: High | Cloudflare reaches your server over https The visitor arrives over https and Cloudflare reaches your server over https as well. |
| FailedConfidence: High | Cloudflare reaches your server over plain http Visitors arrive over https, the request reached your server on a plain http port, and nothing answers on port 443. Traffic between Cloudflare and your server travels unencrypted. |
| WarningConfidence: Medium | Cloudflare reaches your server over plain http The same, but port 443 does answer on your server. A local proxy may be handling https in front of WordPress, so the setting is worth checking rather than assumed wrong. |
| WarningConfidence: Low | Cloudflare may be reaching your server over plain http The request arrived on a plain http port, and the plugin could not reach port 443 to tell whether https is available there. |
| Could not checkConfidence: Low | This check could not be completed Cloudflare did not report the scheme the visitor used, the server answered on a port that is neither https nor a known http port, or no test request reached the server. The reason is named below. |
| Not applicable | Cloudflare is not in front of this site Check A1 did not detect Cloudflare, so this check sent no request. Reason not_behind_cloudflare. |
When the result names a reason
token_missing: The test request never reached your server, so there was nothing to compare. On A2 the plugin uses it for three cases: the test request never reached your server, Cloudflare did not report the visitor scheme, or the port was not one the plugin recognises.no_snapshot: This check needs a recent visit through Cloudflare. Open the Edge Doctor report once and it will have one. Scheduled runs and WP-CLI have no visitor request of their own. They use a stored visit no older than 7 days; opening the report once in the admin creates one.qs_ignored: Your cache key ignores the query string, so the plugin cannot test a page without risking a cached copy of it. Before it asks for any private address, the plugin requests your home page twice with a different unique query string. If either answer is aHIT, your cache key ignores the query string, and a test request could store a private page under an address visitors use. So the plugin stops and sends nothing.blocked_by_config: WordPress itself refused the requests from your site to itself, so none was sent. WP_HTTP_BLOCK_EXTERNAL is on, and your own address is not let through. The plugin links this result to its own guide: WordPress blocks requests to your own site.not_behind_cloudflare: This site is not behind Cloudflare.
Symptoms you may notice
- Usually nothing visible: the browser shows the padlock, because the visitor’s half of the connection is encrypted. That is why Flexible SSL goes unnoticed.
- A redirect loop (the browser reports too many redirects) once the server or a plugin redirects http to https. Cloudflare asks for http, the server redirects to https, and Cloudflare asks for http again.
- WordPress building http:// links or mixed content warnings, unless a plugin sets
HTTPStoon. When such a plugin is active, the result names it.
Why it happens
The SSL/TLS encryption mode of your Cloudflare zone is Flexible. In that mode “traffic from visitors to Cloudflare can be encrypted via HTTPS, but traffic from Cloudflare to the origin server is not” (Cloudflare: encryption modes). It is often chosen because the server has no certificate yet, and it makes the padlock appear without one.
WordPress decides whether a request is secure with is_ssl(), which looks at $_SERVER['HTTPS'] and, when that is not set, at port 443. Over Flexible SSL neither is true, so plugins made for Flexible SSL set HTTPS to on. That hides the problem from WordPress but does not encrypt anything.
Confirm it by hand
1. Read the mode. In the Cloudflare dashboard, open your zone, then SSL/TLS, Overview, and see which encryption mode is selected.
2. Ask your server directly whether it speaks https. From any computer, connect to your server’s own address while sending your domain name. Replace the address with your server IP (your host shows it, and the Edge Doctor evidence shows it masked):
curl -svo /dev/null --resolve example.com:443:203.0.113.10 https://example.com/Connection refused or a timeout means nothing listens on port 443, which matches the Failed result. A completed handshake prints the certificate subject and issuer; if curl complains about the certificate, run it again with -k to read it anyway, and see check A5.
How to fix it
Change things in this order. Switching Cloudflare to Full (strict) before the server has a valid certificate takes the site down with error 521, 525 or 526.
1. Put a certificate on your server. Either a Cloudflare Origin CA certificate, or one from a public authority such as Let’s Encrypt, which most hosting panels issue. An Origin CA certificate is meant only for traffic that arrives through proxied records; visitors who reach the server directly would see a certificate warning.
2. Set the encryption mode to Full (strict). Cloudflare then connects over https and validates the certificate, from a public authority or from the Origin CA.
3. Clean up WordPress. Remove any plugin that forces https for Flexible SSL, and make sure the WordPress Address and Site Address under Settings, General start with https (check A3).
If your host runs its own proxy that handles https before WordPress (the Warning with Medium confidence), ask the host which mode they expect; Full (strict) is the one that validates the certificate.
Limitations
The plugin judges by the port the request reached PHP on. A proxy on the server that receives https and passes plain http to PHP looks the same as Flexible SSL, which is why that case is only a Warning.
To test port 443 the plugin tries 127.0.0.1, the address the server knows itself by and its outgoing address when that is not a Cloudflare address. A firewall that drops those connections gives the Warning with Low confidence, not a finding.
Ports other than 443, 80, 8080, 8000 and 8008 are not decided either way.
Related checks
- A5 Certificate on your server: reads the certificate on port 443 once https is in place.
- A3 WordPress addresses still on http: WordPress addresses that still start with http://.
- A4 Redirect loops and HTTP to HTTPS: redirect loops, which Flexible SSL often causes.
- E3 Cloudflare 52x errors: 525 and 526 errors after switching the mode too early.
Sources
Run this check on your own site with Edge Doctor for Cloudflare®, free on WordPress.org.
Edge Doctor for Cloudflare® is not affiliated with or endorsed by Cloudflare, Inc. Cloudflare is a registered trademark of Cloudflare, Inc.