From 30c0da58819892f414d09b98d6d4afe13bcecd3e Mon Sep 17 00:00:00 2001 From: Dane Knecht Date: Sat, 11 Apr 2026 13:29:30 -0500 Subject: [PATCH 01/13] Add cache troubleshooting for login flows --- .../dynamic-content-and-login-issues.mdx | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/content/docs/cache/troubleshooting/dynamic-content-and-login-issues.mdx diff --git a/src/content/docs/cache/troubleshooting/dynamic-content-and-login-issues.mdx b/src/content/docs/cache/troubleshooting/dynamic-content-and-login-issues.mdx new file mode 100644 index 00000000000..b02d5a088d3 --- /dev/null +++ b/src/content/docs/cache/troubleshooting/dynamic-content-and-login-issues.mdx @@ -0,0 +1,87 @@ +--- +title: Dynamic content and login issues +pcx_content_type: troubleshooting +description: Troubleshoot login failures, missing session cookies, and challenge loops caused by caching dynamic content. +sidebar: + order: 2 +--- + +Dynamic pages such as login forms, checkout flows, and authenticated application routes can break when they are cached too aggressively. + +Common symptoms include: + +- Users can load the login page, but the sign-in form fails after submission. +- Sessions do not persist after a successful sign-in. +- The origin sends a `Set-Cookie` header, but the browser never stores the cookie. +- A challenge page appears, but after solving it the user returns to the login page or loses form state. + +## Cached login page strips session cookies + +One common cause is a [Cache Rule](/cache/how-to/cache-rules/) or legacy Page Rule configured to cache dynamic HTML. + +This usually happens when all of the following are true: + +- The page is configured as **Eligible for cache** or **Cache Everything**. +- The response is dynamic HTML such as `/login` or `/account`. +- The origin sends a `Set-Cookie` header. +- An [Edge TTL](/cache/how-to/cache-rules/settings/#edge-ttl) or status-code TTL overrides origin cache directives. + +In this configuration, Cloudflare can cache the response and remove the `Set-Cookie` header before the response is stored at the edge. As a result, the browser receives the login page but never gets the session cookie required for the next request. + +### How to confirm + +Check the response for the login page or other dynamic route. + +If you see both of the following, the page is probably cached when it should not be: + +- `CF-Cache-Status: HIT` or `CF-Cache-Status: EXPIRED` +- No `Set-Cookie` header in the response, even though your origin usually sets one + +You may also see framework-specific failures after form submission, for example: + +- A redirect back to the login page +- A `403` or `500` after sign-in +- CSRF validation errors +- Missing server-side session state + +This issue is common with frameworks that rely on a session or CSRF cookie on the first page load, including JavaServer Faces, ASP.NET, PHP session handlers, Django, Rails, and Laravel. + +### Resolution + +Do not cache login pages or other authenticated HTML. + +Instead: + +1. Restrict **Eligible for cache** or **Cache Everything** to static paths only. +2. Add a more specific Cache Rule that bypasses or disables caching for routes such as `/login`, `/account`, `/cart`, `/checkout`, and application API paths. +3. If the origin must control caching, remove any Edge TTL override that forces the page to be cached. +4. Verify the fixed response now returns `CF-Cache-Status: DYNAMIC`, `MISS`, or `BYPASS`, and preserves `Set-Cookie`. + +For more information on cookie behavior, refer to [Interaction of Set-Cookie response header with Cache](/cache/concepts/cache-behavior/#interaction-of-set-cookie-response-header-with-cache). + +## Challenge loops on login or form flows + +Security challenges can also interrupt dynamic flows. + +Two common patterns are: + +- A challenge is triggered on the initial `GET` request for the login page. The user solves the challenge, but the application loses the original session or CSRF context. +- A challenge is triggered on the `POST` request that submits the login form or other sensitive action. The browser may have to repeat the request after the challenge, which can break the original form submission. + +### How to confirm + +Check whether a [WAF custom rule](/waf/custom-rules/), [managed rule](/waf/managed-rules/), or [rate limiting rule](/waf/rate-limiting-rules/) applies to the login path. + +If the issue only affects routes such as `/login`, `/signin`, `/checkout`, or `/api/auth/*`, and the application works when the challenge is disabled for those paths, the challenge is likely interrupting the flow. + +### Resolution + +Use one of the following approaches: + +1. Exclude the login or form submission path from the challenge rule. +2. Narrow the rule expression so it applies to suspicious traffic only. +3. If you must protect the route, use a less disruptive control on the page load and apply stronger actions elsewhere in the flow. + +When debugging, also verify that rules are not matching Cloudflare-generated paths such as `/cdn-cgi/*`. + +For more information on challenge-related behavior, refer to [Rules troubleshooting](/rules/reference/troubleshooting/) and [Cloudflare WAF troubleshooting](/waf/troubleshooting/). From d9f86b3bc393ae63764bb96469210046c67134fd Mon Sep 17 00:00:00 2001 From: Dane Knecht Date: Sat, 11 Apr 2026 13:29:33 -0500 Subject: [PATCH 02/13] Expand DNS troubleshooting guidance --- .../docs/dns/troubleshooting/dns-issues.mdx | 14 ++++++++ .../docs/dns/troubleshooting/email-issues.mdx | 35 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/content/docs/dns/troubleshooting/dns-issues.mdx b/src/content/docs/dns/troubleshooting/dns-issues.mdx index ee3db2e55c4..d3a78d5ab37 100644 --- a/src/content/docs/dns/troubleshooting/dns-issues.mdx +++ b/src/content/docs/dns/troubleshooting/dns-issues.mdx @@ -57,6 +57,20 @@ In rare cases, the DNS resolver in the client requesting the URL might fail to r Reload the page after a short wait to note if the problem disappears. This issue is unrelated to Cloudflare, but using [Cloudflare's DNS resolver](/1.1.1.1/setup/) may help. Contact your hosting provider for additional help with your current DNS resolver. +### Newly created record still does not resolve + +If you recently created a DNS record and resolvers still return `NXDOMAIN` or no answer, the previous negative response may still be cached. + +For new records, many resolvers use the zone's negative caching TTL rather than the new record's TTL. This negative cache duration is typically taken from the `MINIMUM` field in the zone's `SOA` record, as described in [RFC 2308](https://datatracker.ietf.org/doc/html/rfc2308). + +This means: + +- Lowering the TTL on the new record does not clear an existing negative cache entry. +- Flushing your local DNS cache only affects your own device. +- Different recursive resolvers may recover at different times depending on when they cached the negative answer. + +To confirm, query the zone's `SOA` record and check the negative caching value. Then wait for that interval to expire before testing again. + ### Account recovery If you are locked out of the Cloudflare account that contains your DNS configuration, refer to [Account recovery](/fundamentals/user-profiles/account-recovery/). diff --git a/src/content/docs/dns/troubleshooting/email-issues.mdx b/src/content/docs/dns/troubleshooting/email-issues.mdx index e7896f59b1b..224ba5096f7 100644 --- a/src/content/docs/dns/troubleshooting/email-issues.mdx +++ b/src/content/docs/dns/troubleshooting/email-issues.mdx @@ -35,6 +35,41 @@ Also, if `CNAME` records are not returned by the queried nameserver (sometimes n Cloudflare does not proxy traffic on port 25 (SMTP) unless [Cloudflare Spectrum](/spectrum/reference/configuration-options#smtp) is turned on and configured to proxy email traffic across Cloudflare. If you do not have Spectrum turned on, then no email traffic (SMTP) passes through Cloudflare, and Cloudflare only resolves the DNS. This also means that any DNS record used to send email traffic must be DNS-only to bypass the Cloudflare network. For more information, refer to [Identifying subdomains compatible with Cloudflare's proxy](/dns/proxy-status/). +## Is your mail hostname proxied? + +Mail protocols such as SMTP, IMAP, and POP3 do not work through Cloudflare's standard HTTP proxy. + +If the hostname used for mail resolves to a Cloudflare IP address, the record is proxied and mail clients will not be able to connect correctly. + +Common examples include: + +- `mail.example.com` used for SMTP, IMAP, or POP3 +- Any hostname targeted by your `MX` record +- Autodiscover or mail service hostnames that must return the provider's actual DNS target + +To fix this issue: + +1. Go to **DNS** > **Records**. +2. Locate the mail-related hostname. +3. Change the [proxy status](/dns/proxy-status/) to **DNS only**. + +Your `MX` record itself is always DNS-only, but the hostname it points to must also resolve to a DNS-only target. + +## Common provider record values + +If you are not sure whether the DNS content itself is correct, compare it with the values from your provider. + +Common examples include: + +| Provider | MX records | SPF record | +| --- | --- | --- | +| Google Workspace | `ASPMX.L.GOOGLE.COM` (priority `1`), `ALT1.ASPMX.L.GOOGLE.COM` and `ALT2.ASPMX.L.GOOGLE.COM` (priority `5`), `ALT3.ASPMX.L.GOOGLE.COM` and `ALT4.ASPMX.L.GOOGLE.COM` (priority `10`) | `v=spf1 include:_spf.google.com ~all` | +| Microsoft 365 | `.mail.protection.outlook.com` (priority `0`) | `v=spf1 include:spf.protection.outlook.com -all` | +| iCloud Mail | `mx01.mail.icloud.com` and `mx02.mail.icloud.com` (priority `10`) | `v=spf1 include:icloud.com ~all` | +| Mailgun | `mxa.mailgun.org` and `mxb.mailgun.org` (priority `10`) | `v=spf1 include:mailgun.org ~all` | + +Always confirm the exact values with your provider before making changes. + ## Contact your mail provider for assistance If your email does not work shortly after editing DNS records, contact your mail administrator or mail provider for further assistance in troubleshooting so that data about the issue can be provided to Cloudflare support. From c6a476fba8a286942d908951dfdb30bc7dd363d1 Mon Sep 17 00:00:00 2001 From: Dane Knecht Date: Sat, 11 Apr 2026 13:29:37 -0500 Subject: [PATCH 03/13] Expand registrar transfer troubleshooting --- src/content/docs/registrar/troubleshooting.mdx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/content/docs/registrar/troubleshooting.mdx b/src/content/docs/registrar/troubleshooting.mdx index 05d8bb591fc..9364fa833fc 100644 --- a/src/content/docs/registrar/troubleshooting.mdx +++ b/src/content/docs/registrar/troubleshooting.mdx @@ -78,6 +78,14 @@ Domains with certain WHOIS statuses cannot be transferred: - `redemptionPeriod` — the domain has expired and passed the grace period. You must restore and renew it at your current registrar before it can be transferred. - `pendingDelete` — the domain is scheduled for deletion by the registry and cannot be transferred or recovered. After deletion, the domain becomes available for anyone to register. +Other common WHOIS or RDAP statuses include: + +- `clientTransferProhibited` — the domain is locked at the registrar. +- `serverTransferProhibited` — the registry has applied a transfer restriction. +- `addPeriod` — the domain is within the post-registration lock window. +- `pendingTransfer` — the domain is already in an active transfer. +- `clientDeleteProhibited` or `serverDeleteProhibited` — deletion is restricted. + ## WHOIS privacy is blocking the transfer Most domains can be transferred with WHOIS privacy enabled. However, some registrars may prohibit transfer requests if you have WHOIS privacy services enabled. If your transfer is failing, check with your current registrar to confirm WHOIS privacy is not blocking it. @@ -111,6 +119,16 @@ Verification is triggered when your registrant contact email differs from your v Some TLDs — including `.mx`, `.nz`, and `.ca` — may send verification through a third-party service. In these cases, the verification email will come from `noreply@emailverification.info` rather than Cloudflare. Check your spam folder if you do not receive it. +For these TLDs, if verification is not completed in time, the registry may temporarily replace your nameservers with `ns1.emailverification.info` and related hostnames until the registrant email is verified. + +## `.uk` transfer uses an IPS tag, not an auth code + +`.uk`, `.co.uk`, and `.org.uk` domains do not use the standard auth-code transfer flow. + +Instead, the losing registrar changes the domain's IPS tag to the gaining registrar. If you are transferring a `.uk` family domain to Cloudflare and cannot find an auth-code field, this behavior is expected. + +If the transfer does not proceed, contact the current registrar and confirm that they have updated the IPS tag correctly. + ## Restart your transfer :::note From f768cdc3d0e4335a15b29e4e717f1c067ccd7fb3 Mon Sep 17 00:00:00 2001 From: Dane Knecht Date: Sat, 11 Apr 2026 13:29:41 -0500 Subject: [PATCH 04/13] Document Origin CA expiry alert limitation --- src/content/docs/ssl/origin-configuration/origin-ca/index.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/content/docs/ssl/origin-configuration/origin-ca/index.mdx b/src/content/docs/ssl/origin-configuration/origin-ca/index.mdx index e6f8c7aadd4..0d48f3b1ae2 100644 --- a/src/content/docs/ssl/origin-configuration/origin-ca/index.mdx +++ b/src/content/docs/ssl/origin-configuration/origin-ca/index.mdx @@ -35,6 +35,10 @@ Refer to [Troubleshooting](/ssl/origin-configuration/origin-ca/troubleshooting/# Using Cloudflare origin CA certificates does not prevent you from using [delegated DCV](/ssl/edge-certificates/changing-dcv-method/methods/delegated-dcv/). ::: +:::note[Known limitation] +Cloudflare does not currently send expiration notifications for origin CA certificates. If you rely on long-lived origin CA certificates, track their expiration in your own certificate inventory or monitoring system. +::: + --- ## Deploy an Origin CA certificate From 55fc0a9cbdddfb7d36baad00f51faa3a149b8bf3 Mon Sep 17 00:00:00 2001 From: Dane Knecht Date: Sat, 11 Apr 2026 13:29:45 -0500 Subject: [PATCH 05/13] Add Cloudflare One troubleshooting details --- .../integrations/identity-providers/one-time-pin.mdx | 11 +++++++++++ .../troubleshoot-tunnels/common-errors.mdx | 11 ++++++++++- .../cloudflare-one/team-and-resources/users/scim.mdx | 10 ++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/content/docs/cloudflare-one/integrations/identity-providers/one-time-pin.mdx b/src/content/docs/cloudflare-one/integrations/identity-providers/one-time-pin.mdx index 72a4ee55148..e6682dae55f 100644 --- a/src/content/docs/cloudflare-one/integrations/identity-providers/one-time-pin.mdx +++ b/src/content/docs/cloudflare-one/integrations/identity-providers/one-time-pin.mdx @@ -85,3 +85,14 @@ By design, blocked users will not receive an email. The login page will always s Access only logs an authentication attempt after the user enters a code. If the user enters their email but never submits a code, the event will not appear in your [audit logs](/cloudflare-one/insights/logs/dashboard-logs/access-authentication-logs/#authentication-logs). ::: + +## OTP behavior and limits + +Keep the following behavior in mind when troubleshooting OTP logins: + +- Each PIN is single-use. +- Requesting a new PIN invalidates the previous PIN. +- Cloudflare only sends the email if the user is allowed by an Access policy. +- Third-party mail security tools may consume the link before the user does, which makes the code appear already used. + +If users repeatedly fail to sign in, request a fresh code and verify that your mail filtering or link-scanning product is allowlisting `noreply@notify.cloudflare.com`. diff --git a/src/content/docs/cloudflare-one/networks/connectors/cloudflare-tunnel/troubleshoot-tunnels/common-errors.mdx b/src/content/docs/cloudflare-one/networks/connectors/cloudflare-tunnel/troubleshoot-tunnels/common-errors.mdx index 36328414b54..b931eaf57ef 100644 --- a/src/content/docs/cloudflare-one/networks/connectors/cloudflare-tunnel/troubleshoot-tunnels/common-errors.mdx +++ b/src/content/docs/cloudflare-one/networks/connectors/cloudflare-tunnel/troubleshoot-tunnels/common-errors.mdx @@ -45,6 +45,16 @@ The tunnel status only reflects the connection between `cloudflared` and the Clo Long-lived connections initiated through Cloudflare One, such as SSH sessions, can last up to eight hours. However, disruptions along the service path may result in more frequent disconnects. Often, these disconnects are caused by regularly scheduled maintenance events such as data center, server, or service updates and restarts. If you believe these events are not the cause of disconnects in your environment, collect the relevant [client logs](/cloudflare-one/team-and-resources/devices/cloudflare-one-client/troubleshooting/diagnostic-logs/) and [Tunnel logs](/cloudflare-one/networks/connectors/cloudflare-tunnel/monitor-tunnels/logs/) and contact Support. +If the disconnects mainly affect idle SSH sessions, WebSocket connections, or other long-lived connections, the transport protocol may be relevant. + +When `cloudflared` uses QUIC, idle sessions can be more sensitive to network devices that aggressively time out UDP traffic. If idle connections drop repeatedly, try one or more of the following: + +- Configure application-layer keepalives, such as `ServerAliveInterval` for SSH. +- Test with `cloudflared` set to `protocol: http2`. +- Review local firewalls, NAT devices, and upstream network equipment for short UDP idle timers. + +For connection setup failures caused by blocked QUIC traffic, refer to the QUIC troubleshooting sections above. + ## `ping` and `traceroute` commands do not work. To ping an IP address behind Cloudflare Tunnel, your system must allow ICMP traffic through `cloudflared`. For configuration instructions, refer to the [ICMP proxy documentation](/cloudflare-one/traffic-policies/proxy/#icmp). @@ -61,4 +71,3 @@ If you added a [multi-level subdomain](/cloudflare-one/networks/connectors/cloud For more information on Tunnel errors, view your [Tunnel logs](/cloudflare-one/networks/connectors/cloudflare-tunnel/monitor-tunnels/logs/) or [contact Cloudflare Support](/support/contacting-cloudflare-support/). - diff --git a/src/content/docs/cloudflare-one/team-and-resources/users/scim.mdx b/src/content/docs/cloudflare-one/team-and-resources/users/scim.mdx index 42d60886593..317d2010bcb 100644 --- a/src/content/docs/cloudflare-one/team-and-resources/users/scim.mdx +++ b/src/content/docs/cloudflare-one/team-and-resources/users/scim.mdx @@ -28,3 +28,13 @@ Cloudflare Access can automatically deprovision users from Zero Trust after they To set up SCIM for Zero Trust, refer to our [SSO integration](/cloudflare-one/integrations/identity-providers/) guides. +## Common provider-specific issues + +SCIM behavior depends on the identity provider configuration as well as Cloudflare. + +Common issues include: + +- **Okta**: User sync and group sync are separate. Make sure **Push Groups** is configured if you expect groups to appear in Zero Trust policies. +- **Microsoft Entra ID**: Group sync only occurs for groups included in the provisioning scope. The `userName` attribute should match the user's email address in Cloudflare One. + +If users appear but groups do not, verify the IdP-side SCIM app first before troubleshooting Cloudflare policy behavior. From db16a6f6ed968500b041d626f2f967182a239afe Mon Sep 17 00:00:00 2001 From: Dane Knecht Date: Sat, 11 Apr 2026 13:29:48 -0500 Subject: [PATCH 06/13] Add WAF rule interaction guidance --- src/content/docs/waf/concepts.mdx | 2 + .../legacy/old-rate-limiting/upgrade.mdx | 2 + .../troubleshooting/phase-interactions.mdx | 80 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 src/content/docs/waf/troubleshooting/phase-interactions.mdx diff --git a/src/content/docs/waf/concepts.mdx b/src/content/docs/waf/concepts.mdx index 8c5b9b37f68..74f36a02cd1 100644 --- a/src/content/docs/waf/concepts.mdx +++ b/src/content/docs/waf/concepts.mdx @@ -74,3 +74,5 @@ Cloudflare evaluates different types of rules when processing incoming requests. Rules are evaluated in order. If there is a match for a rule with a [terminating action](/ruleset-engine/rules-language/actions/), the rule evaluation will stop and the action will be executed immediately. Rules with a non-terminating action (such as _Log_) will not prevent subsequent rules from being evaluated and executed. For more information on how rules are evaluated, refer to [Rule evaluation](/ruleset-engine/about/rules/#rule-evaluation) in the Ruleset Engine documentation. For more information on the phases where each WAF feature will execute, refer to [WAF phases](/waf/reference/phases/). + +For common interactions between rewrites, IP Access rules, custom rules, and managed rules, refer to [Rule phase interactions](/waf/troubleshooting/phase-interactions/). diff --git a/src/content/docs/waf/reference/legacy/old-rate-limiting/upgrade.mdx b/src/content/docs/waf/reference/legacy/old-rate-limiting/upgrade.mdx index 464baede844..d107fc85d2e 100644 --- a/src/content/docs/waf/reference/legacy/old-rate-limiting/upgrade.mdx +++ b/src/content/docs/waf/reference/legacy/old-rate-limiting/upgrade.mdx @@ -28,6 +28,8 @@ You must now use the [Rulesets API](/ruleset-engine/rulesets-api/) and the [`clo - **Advanced scope expressions:** The previous version of Rate Limiting allowed you to scope the rules based on a single path and method of the request. In the new version, you can write rules similar to [WAF custom rules](/waf/custom-rules/), combining multiple parameters of the HTTP request. +- **Counter scope:** The previous version relied on a global counter model. The new version of rate limiting uses counters scoped per data center, with `cf.colo.id` always included as a characteristic. This means thresholds can behave differently for traffic distributed across multiple Cloudflare locations. For more information, refer to [How Cloudflare determines the request rate](/waf/rate-limiting-rules/request-rate/). + - **Separate counting and mitigation expressions:** In the new version of Rate Limiting, counting and mitigation expressions are separate (for Business and Enterprise customers). The counting expression defines which requests are used to compute the rate. The mitigation expression defines which requests are mitigated once the threshold has been reached. Using these separate expressions, you can track the rate of requests on a specific path such as `/login` and, when an IP exceeds the threshold, block every request from the same IP addressed at your domain. - **Additional counting dimensions (Advanced Rate Limiting only):** Like in the previous version of Rate Limiting, customers with the new Rate Limiting get IP-based rate limiting, where Cloudflare counts requests based on the source IP address of incoming requests. In addition to IP-based rate limiting, customers with the new Rate Limiting who subscribe to Advanced Rate Limiting can group requests based on other characteristics, such as the value of API keys, cookies, session headers, ASN, query parameters, or a specific JSON body field. Refer to [Rate limiting best practices](/waf/rate-limiting-rules/best-practices/) for examples. diff --git a/src/content/docs/waf/troubleshooting/phase-interactions.mdx b/src/content/docs/waf/troubleshooting/phase-interactions.mdx new file mode 100644 index 00000000000..d7acf1c8739 --- /dev/null +++ b/src/content/docs/waf/troubleshooting/phase-interactions.mdx @@ -0,0 +1,80 @@ +--- +title: Rule phase interactions +pcx_content_type: troubleshooting +description: Understand how request rewrites, IP Access rules, custom rules, and managed rules interact across WAF phases. +sidebar: + order: 4 +--- + +Cloudflare evaluates request processing features in phases. A rule that appears correct in isolation can behave differently when another product has already modified or terminated the request. + +## Custom rules see the rewritten URL + +Cloudflare applies [URL Rewrite Rules](/rules/transform/url-rewrite/) before [WAF custom rules](/waf/custom-rules/). + +If a Transform Rule rewrites `/public-login` to `/internal/login`, later WAF phases will evaluate the rewritten path. + +### What this means + +- A custom rule matching `/public-login` may not fire after the rewrite. +- A custom rule matching `/internal/login` may fire even though the visitor requested `/public-login`. + +### Resolution + +When troubleshooting a custom rule, check whether a rewrite rule already changed the URL before WAF evaluation. + +For more information, refer to [Rules execution order](/rules/transform/request-header-modification/#execution-order) and [WAF phases](/waf/reference/phases/). + +## IP Access rules can bypass custom rules + +[IP Access rules](/waf/tools/ip-access-rules/) run before WAF custom rules. + +If an IP Access rule with an **Allow** action matches a request, Cloudflare will not evaluate later custom rules for that request. + +### What this means + +- A custom rule may appear to "not fire" for a specific IP even though the expression is correct. +- Allowlisting a source too early can also prevent other WAF logic from running. + +### Resolution + +If a request is unexpectedly bypassing a custom rule, check for matching IP Access rules first. + +## Skip and Allow do not behave the same way + +In the custom rules phase, **Allow** and **Skip** solve different problems. + +- **Allow** stops evaluation in the custom rules phase. +- **Skip** can instruct Cloudflare to skip later products or components, such as managed rules. + +### What this means + +- An **Allow** action in a custom rule does not automatically prevent a later managed rule from blocking the request. +- A **Skip** action can be used to suppress later managed rule evaluation for matching traffic. + +### Resolution + +If a request still hits a managed rule after matching a custom rule, use a [WAF exception](/waf/managed-rules/waf-exceptions/) or a custom rule with a **Skip** action instead of **Allow**. + +## Page Rules do not use the same request view as modern rules + +[Page Rules](/rules/page-rules/) are legacy behavior and do not line up exactly with modern Rules products. + +In mixed configurations, you may see: + +- A rewrite affecting custom rules and managed rules +- Different results between a Page Rule and a modern rule that appear to target the same path + +### Resolution + +When possible, migrate older Page Rules behavior to the current Rules products so the request is evaluated in one model. + +## Recommended troubleshooting workflow + +When a WAF decision looks wrong: + +1. Check for earlier request rewrites. +2. Check for matching IP Access rules. +3. Confirm whether the request was expected to stop in the custom rules phase or skip later phases. +4. Review whether a managed rule still ran after a custom rule match. +5. Use [Trace](/waf/tools/trace/) when available to confirm the actual phase-by-phase result. From ad2c0d3b48888d004f5204737d1a2600c377b22d Mon Sep 17 00:00:00 2001 From: Dane Knecht Date: Sat, 11 Apr 2026 13:29:55 -0500 Subject: [PATCH 07/13] Document AWS route issue for 523 --- .../http-status-codes/cloudflare-5xx-errors/error-523.mdx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/content/docs/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-523.mdx b/src/content/docs/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-523.mdx index 3e5bd335c82..dbec8705190 100644 --- a/src/content/docs/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-523.mdx +++ b/src/content/docs/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/error-523.mdx @@ -12,12 +12,15 @@ This error occurs when Cloudflare cannot contact your origin web server. This typically occurs when a network device between Cloudflare and the origin web server does not have a route to the origin's IP address. +In AWS environments, a common cause is an overly broad route such as `172.0.0.0/8` in a VPC route table. Cloudflare uses public IP ranges in `172.64.0.0/13`, and a broad route can accidentally capture traffic intended for Cloudflare. + ### Resolution Contact your hosting provider and share the necessary [error details](/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/#required-error-details-for-hosting-provider) to exclude the following common causes at your origin web server: - Confirm the correct origin IP address is listed for A or AAAA records within your Cloudflare DNS app. - Troubleshoot Internet routing issues between your origin and Cloudflare, or with the origin itself. +- In AWS, review VPC route tables and make sure you are not sending `172.64.0.0/13` toward a private destination. If required, add a more specific route for `172.64.0.0/13` to your Internet Gateway. If none of the above leads to a resolution, request the following information from your hosting provider or site administrator: From 9f04717b37964a27343cf278a4eede8959865b3f Mon Sep 17 00:00:00 2001 From: Dane Knecht Date: Sat, 11 Apr 2026 13:30:00 -0500 Subject: [PATCH 08/13] Add HTTP/3 troubleshooting guidance --- .../protocol-troubleshooting.mdx | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/content/docs/speed/optimization/protocol/troubleshooting/protocol-troubleshooting.mdx b/src/content/docs/speed/optimization/protocol/troubleshooting/protocol-troubleshooting.mdx index 60a8af83594..2c12846875a 100644 --- a/src/content/docs/speed/optimization/protocol/troubleshooting/protocol-troubleshooting.mdx +++ b/src/content/docs/speed/optimization/protocol/troubleshooting/protocol-troubleshooting.mdx @@ -33,3 +33,25 @@ These errors do not necessarily indicate a protocol-level issue. Follow these st 3. If the issue does not persist, analyze netlogs for HTTP/2 or HTTP/3-specific issues. For more information, refer to [Chromium URL Request Header](https://chromium.googlesource.com/chromium/src/+/HEAD/net/url_request/url_request.h). + +## Chrome stalls or fails only on HTTP/3 + +If the issue reproduces only in Chrome over HTTP/3 and disappears when HTTP/3 is disabled, the problem may be related to a browser-side QUIC handling issue rather than your origin server. + +Symptoms can include: + +- Large downloads stall unexpectedly. +- Pages with many concurrent requests hang for one to three minutes and then fail. +- Chrome reports `ERR_QUIC_PROTOCOL_ERROR` or another QUIC-related browser error after the connection stops making progress. + +### How to isolate the issue + +1. Temporarily disable HTTP/3 for the zone. +2. Test the same request again over HTTP/2. +3. If the issue disappears over HTTP/2, capture a NetLog for Chrome and compare the behavior. + +### Resolution + +If the issue is limited to specific hostnames, you can test a more targeted workaround such as removing the `Alt-Svc` header with a [response header transform rule](/rules/transform/response-header-modification/). However, proxied hostnames can also advertise HTTP/3 through generated HTTPS records. Disabling HTTP/3 for the zone is the most reliable way to force HTTP/2 while you troubleshoot. + +After changing `Alt-Svc`, remember that browsers may cache the advertised alternative service for up to 24 hours. From 92d26b6853c561ce190710a6048a8d155548dd66 Mon Sep 17 00:00:00 2001 From: Pedro Sousa <680496+pedrosousa@users.noreply.github.com> Date: Mon, 13 Apr 2026 10:52:25 +0100 Subject: [PATCH 09/13] Fix link URL --- src/content/docs/waf/troubleshooting/phase-interactions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/waf/troubleshooting/phase-interactions.mdx b/src/content/docs/waf/troubleshooting/phase-interactions.mdx index d7acf1c8739..769bf22f0f5 100644 --- a/src/content/docs/waf/troubleshooting/phase-interactions.mdx +++ b/src/content/docs/waf/troubleshooting/phase-interactions.mdx @@ -77,4 +77,4 @@ When a WAF decision looks wrong: 2. Check for matching IP Access rules. 3. Confirm whether the request was expected to stop in the custom rules phase or skip later phases. 4. Review whether a managed rule still ran after a custom rule match. -5. Use [Trace](/waf/tools/trace/) when available to confirm the actual phase-by-phase result. +5. Use [Trace](/rules/trace-request/) when available to confirm the actual phase-by-phase result. From 3303d23c9dcc7ebf6d7b1762db9411e471186b37 Mon Sep 17 00:00:00 2001 From: Pedro Sousa <680496+pedrosousa@users.noreply.github.com> Date: Mon, 13 Apr 2026 16:29:27 +0100 Subject: [PATCH 10/13] WAF updates --- .../troubleshooting/phase-interactions.mdx | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/content/docs/waf/troubleshooting/phase-interactions.mdx b/src/content/docs/waf/troubleshooting/phase-interactions.mdx index 769bf22f0f5..e0d15beabed 100644 --- a/src/content/docs/waf/troubleshooting/phase-interactions.mdx +++ b/src/content/docs/waf/troubleshooting/phase-interactions.mdx @@ -6,24 +6,24 @@ sidebar: order: 4 --- -Cloudflare evaluates request processing features in phases. A rule that appears correct in isolation can behave differently when another product has already modified or terminated the request. +Cloudflare evaluates request processing features in [phases](/ruleset-engine/about/phases/). A rule that appears correct in isolation can behave differently when another product has already modified or terminated the request. -## Custom rules see the rewritten URL +## Custom rules are evaluated against the rewritten URL -Cloudflare applies [URL Rewrite Rules](/rules/transform/url-rewrite/) before [WAF custom rules](/waf/custom-rules/). +Cloudflare applies [URL Rewrite Rules](/rules/transform/url-rewrite/) before [custom rules](/waf/custom-rules/). -If a Transform Rule rewrites `/public-login` to `/internal/login`, later WAF phases will evaluate the rewritten path. +If a transform rule rewrites `/public-login` to `/internal/login`, later WAF phases will evaluate the rewritten path. -### What this means +This means that: - A custom rule matching `/public-login` may not fire after the rewrite. - A custom rule matching `/internal/login` may fire even though the visitor requested `/public-login`. ### Resolution -When troubleshooting a custom rule, check whether a rewrite rule already changed the URL before WAF evaluation. +When troubleshooting a custom rule, check whether a rewrite rule already changed the URL before WAF evaluation. You can use [Trace](/rules/trace-request/) to check the evaluation order of your rules based on an example request. -For more information, refer to [Rules execution order](/rules/transform/request-header-modification/#execution-order) and [WAF phases](/waf/reference/phases/). +For more information, refer to the request execution order in [Phases list](/ruleset-engine/reference/phases-list/#application-layer). ## IP Access rules can bypass custom rules @@ -33,8 +33,8 @@ If an IP Access rule with an **Allow** action matches a request, Cloudflare will ### What this means -- A custom rule may appear to "not fire" for a specific IP even though the expression is correct. -- Allowlisting a source too early can also prevent other WAF logic from running. +- A custom rule may appear to "not fire" for a specific IP address even though the expression is correct. +- Allowlisting a source IP address too early can prevent other app security logic from running (namely custom rules). ### Resolution @@ -42,19 +42,19 @@ If a request is unexpectedly bypassing a custom rule, check for matching IP Acce ## Skip and Allow do not behave the same way -In the custom rules phase, **Allow** and **Skip** solve different problems. +The _Skip_ action available in WAF custom rules has a different behavior from the _Allow_ action in IP Access rules. -- **Allow** stops evaluation in the custom rules phase. -- **Skip** can instruct Cloudflare to skip later products or components, such as managed rules. +The _Allow_ action in IP Access rules bypasses WAF custom rules, rate limiting rules, WAF Managed Rules (except for country-level entries), and deprecated firewall rules. Any matches do not appear in [Security Events](/waf/analytics/security-events/). An allowed request never reaches WAF custom rules, including any logging or tracking rules. -### What this means +The _Skip_ action in WAF custom rules instructs Cloudflare to selectively skip certain app security products or components, such as WAF managed rules. Depending on the configuration of the custom rule with the _Skip_ action, other security products will still evaluate the request and might block it. -- An **Allow** action in a custom rule does not automatically prevent a later managed rule from blocking the request. -- A **Skip** action can be used to suppress later managed rule evaluation for matching traffic. +WAF custom rules do not have an _Allow_ action. To control what a matching request bypasses, you must use the [_Skip_](/waf/custom-rules/skip/) action and select the specific products or phases to skip. ### Resolution -If a request still hits a managed rule after matching a custom rule, use a [WAF exception](/waf/managed-rules/waf-exceptions/) or a custom rule with a **Skip** action instead of **Allow**. +Review your configuration (namely IP Access rules and custom rules with the _Skip_ action) to ensure the intended behavior is achieved. + +If specific rules of [WAF managed rulesets](/waf/managed-rules/) are blocking requests you want to allow, you can create [managed rules exceptions](/waf/managed-rules/waf-exceptions/) to skip specific managed rules or rulesets for particular requests instead of skipping WAF Managed Rules entirely. ## Page Rules do not use the same request view as modern rules @@ -62,7 +62,7 @@ If a request still hits a managed rule after matching a custom rule, use a [WAF In mixed configurations, you may see: -- A rewrite affecting custom rules and managed rules +- A rewrite affecting custom rules and Managed Rules - Different results between a Page Rule and a modern rule that appear to target the same path ### Resolution @@ -71,7 +71,7 @@ When possible, migrate older Page Rules behavior to the current Rules products s ## Recommended troubleshooting workflow -When a WAF decision looks wrong: +When a WAF decision looks incorrect: 1. Check for earlier request rewrites. 2. Check for matching IP Access rules. From 337faf528dd1cd25b43361a09688aa10bfb6573e Mon Sep 17 00:00:00 2001 From: Pedro Sousa <680496+pedrosousa@users.noreply.github.com> Date: Mon, 13 Apr 2026 16:30:41 +0100 Subject: [PATCH 11/13] Removed incorrect difference --- .../docs/waf/reference/legacy/old-rate-limiting/upgrade.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/content/docs/waf/reference/legacy/old-rate-limiting/upgrade.mdx b/src/content/docs/waf/reference/legacy/old-rate-limiting/upgrade.mdx index d107fc85d2e..464baede844 100644 --- a/src/content/docs/waf/reference/legacy/old-rate-limiting/upgrade.mdx +++ b/src/content/docs/waf/reference/legacy/old-rate-limiting/upgrade.mdx @@ -28,8 +28,6 @@ You must now use the [Rulesets API](/ruleset-engine/rulesets-api/) and the [`clo - **Advanced scope expressions:** The previous version of Rate Limiting allowed you to scope the rules based on a single path and method of the request. In the new version, you can write rules similar to [WAF custom rules](/waf/custom-rules/), combining multiple parameters of the HTTP request. -- **Counter scope:** The previous version relied on a global counter model. The new version of rate limiting uses counters scoped per data center, with `cf.colo.id` always included as a characteristic. This means thresholds can behave differently for traffic distributed across multiple Cloudflare locations. For more information, refer to [How Cloudflare determines the request rate](/waf/rate-limiting-rules/request-rate/). - - **Separate counting and mitigation expressions:** In the new version of Rate Limiting, counting and mitigation expressions are separate (for Business and Enterprise customers). The counting expression defines which requests are used to compute the rate. The mitigation expression defines which requests are mitigated once the threshold has been reached. Using these separate expressions, you can track the rate of requests on a specific path such as `/login` and, when an IP exceeds the threshold, block every request from the same IP addressed at your domain. - **Additional counting dimensions (Advanced Rate Limiting only):** Like in the previous version of Rate Limiting, customers with the new Rate Limiting get IP-based rate limiting, where Cloudflare counts requests based on the source IP address of incoming requests. In addition to IP-based rate limiting, customers with the new Rate Limiting who subscribe to Advanced Rate Limiting can group requests based on other characteristics, such as the value of API keys, cookies, session headers, ASN, query parameters, or a specific JSON body field. Refer to [Rate limiting best practices](/waf/rate-limiting-rules/best-practices/) for examples. From b45cc509aefe90041b8c770285d93c7c918f5d1f Mon Sep 17 00:00:00 2001 From: danielegm <74369360+danielegm@users.noreply.github.com> Date: Tue, 14 Apr 2026 14:28:55 +0100 Subject: [PATCH 12/13] Update phase-interactions.mdx (#29831) --- src/content/docs/waf/troubleshooting/phase-interactions.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/waf/troubleshooting/phase-interactions.mdx b/src/content/docs/waf/troubleshooting/phase-interactions.mdx index e0d15beabed..220017bc6f8 100644 --- a/src/content/docs/waf/troubleshooting/phase-interactions.mdx +++ b/src/content/docs/waf/troubleshooting/phase-interactions.mdx @@ -42,11 +42,11 @@ If a request is unexpectedly bypassing a custom rule, check for matching IP Acce ## Skip and Allow do not behave the same way -The _Skip_ action available in WAF custom rules has a different behavior from the _Allow_ action in IP Access rules. +The _Allow_ action in IP Access rules has a different behavior from the _Skip_ action available in WAF custom rules. The _Allow_ action in IP Access rules bypasses WAF custom rules, rate limiting rules, WAF Managed Rules (except for country-level entries), and deprecated firewall rules. Any matches do not appear in [Security Events](/waf/analytics/security-events/). An allowed request never reaches WAF custom rules, including any logging or tracking rules. -The _Skip_ action in WAF custom rules instructs Cloudflare to selectively skip certain app security products or components, such as WAF managed rules. Depending on the configuration of the custom rule with the _Skip_ action, other security products will still evaluate the request and might block it. +The _Skip_ action in WAF custom rules instructs Cloudflare to selectively skip certain application security products or components, such as WAF managed rules. Depending on the configuration of the custom rule with the _Skip_ action, other security products will still evaluate the request and might block it. WAF custom rules do not have an _Allow_ action. To control what a matching request bypasses, you must use the [_Skip_](/waf/custom-rules/skip/) action and select the specific products or phases to skip. From 4e93ebffeff62d6814a54f2bf5a57367bea23f5a Mon Sep 17 00:00:00 2001 From: Hannes <105781579+hannes-cf@users.noreply.github.com> Date: Tue, 14 Apr 2026 15:29:05 +0200 Subject: [PATCH 13/13] [DNS] Expand negative caching troubleshooting section (#29833) * [DNS] Expand negative caching troubleshooting for newly created records * [DNS] Add dig example to check negative cache TTL --- .../docs/dns/troubleshooting/dns-issues.mdx | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/content/docs/dns/troubleshooting/dns-issues.mdx b/src/content/docs/dns/troubleshooting/dns-issues.mdx index d3a78d5ab37..93972b77394 100644 --- a/src/content/docs/dns/troubleshooting/dns-issues.mdx +++ b/src/content/docs/dns/troubleshooting/dns-issues.mdx @@ -59,17 +59,59 @@ Reload the page after a short wait to note if the problem disappears. This issue ### Newly created record still does not resolve -If you recently created a DNS record and resolvers still return `NXDOMAIN` or no answer, the previous negative response may still be cached. +If you recently created a DNS record and resolvers still return `NXDOMAIN` (Non-Existent Domain) or no answer, it is likely because a negative response is currently stored in the resolver's cache. -For new records, many resolvers use the zone's negative caching TTL rather than the new record's TTL. This negative cache duration is typically taken from the `MINIMUM` field in the zone's `SOA` record, as described in [RFC 2308](https://datatracker.ietf.org/doc/html/rfc2308). +When a resolver is queried for a hostname that has no DNS records yet, it caches the empty response so it does not have to ask the authoritative nameserver again immediately. This is known as negative caching. + +For newly created records: + +- The resolver might not have cached the new record yet. Instead, it is using a prior `NXDOMAIN` cache entry that says "this record does not exist," which was generated if the hostname was queried before you created the record. +- The duration of this negative cache is determined by the `MINIMUM` field in your zone's SOA record (per [RFC 2308](https://datatracker.ietf.org/doc/html/rfc2308)), not the TTL of the record you just created. Different resolvers may cache for varying durations. This means: -- Lowering the TTL on the new record does not clear an existing negative cache entry. -- Flushing your local DNS cache only affects your own device. -- Different recursive resolvers may recover at different times depending on when they cached the negative answer. +- Lowering the TTL on your new record will not speed up resolution if a negative cache entry already exists; the resolver will only see your new TTL after the old negative entry expires. +- Flushing your local DNS cache only affects your specific device; the upstream recursive resolver (for example, your ISP or a public provider) still holds the negative result. +- Propagation appears uneven because different resolvers may have queried the name at different times, apply different negative cache TTLs, or have no negative cache entry at all. + +The exact behavior differs per resolver, but to estimate how long you need to wait, query your zone's SOA record and look at the last value (the `MINIMUM` field). You must wait for that interval to pass since the last `NXDOMAIN` query before the new record will consistently resolve. + +You can check if a negative cache entry is active by querying for the non-existent (or newly created) hostname: + +```sh +dig +noall +answer +authority mynewrecord.example.com +``` + +If the record is still negatively cached, the response will include the zone's SOA record in the authority section with a TTL indicating how many seconds remain before the entry expires: + +```txt +example.com. 256 IN SOA ... +``` + +In this example, the negative cache response will continue for 256 more seconds. + +To verify the record resolves correctly, you can purge the cache for public resolvers and query the record. If this works, other resolvers will eventually start resolving as well: + +- [Purge 1.1.1.1 cache](https://one.one.one.one/purge-cache/) +- [Purge 8.8.8.8 cache](https://dns.google/cache) +- [Query 8.8.8.8](https://dns.google/) +- [Query and refresh OpenDNS cache](https://cachecheck.opendns.com/) + +#### Further debugging + +To verify the record was correctly created, query Cloudflare's authoritative nameservers directly: + +```sh +# Find the authoritative nameservers for your zone +dig @1.1.1.1 example.com NS +short +``` + +```sh +# Query the authoritative nameserver for your new record +dig @hera.ns.cloudflare.com mynewrecord.example.com A +``` -To confirm, query the zone's `SOA` record and check the negative caching value. Then wait for that interval to expire before testing again. +Querying the authoritative nameserver directly bypasses resolver caching. If the record is returned, resolvers will eventually start returning it as well. If the record does not appear, verify the record exists in the Cloudflare dashboard and that the hostname matches exactly. ### Account recovery