Runbook 01 · Cloudflare Zero Trust

Cloudflare Access: the 302 that became 401/403

Strict service token authentication changed what a failed machine request looks like. The detection chapter below is free and complete — run it before paying anything. Platform: Cloudflare Zero Trust. Change: 2026-10-02. Detection chapter reviewed: 2026-11-08. The paid chapter is still in re-verification on a live organization; the status notice in the appendix stays until that finishes.

What changed

When the strict service token authentication setting is on for a Zero Trust organization, Access handles requests carrying service token headers differently from the old behaviour:

  • 401 / 403 instead of 302. A failed request no longer gets redirected to the login page. It gets an error, and there is nothing to follow.
  • Only Service Auth policies authorize. Allow policies are ignored for these requests, and so is any CF_Authorization cookie sent with them.
  • No cookie is issued. Successful authentication does not return a CF_Authorization cookie. Later requests must keep sending the service token headers.
  • Failures are logged. Recognized service tokens that fail appear in Access authentication logs under non-identity authentication.
  • It may not be your choice. Organizations created on or after 2026-10-05 have the setting on by default and cannot turn it off.

Detect: are you affected?

Read the organization setting first. This call is read-only.

curl -s "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/organizations" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  | jq '.result.strict_service_token_auth'

true means the new behaviour applies to you now. false means the legacy behaviour still applies — but Cloudflare recommends enabling it, and organizations created on or after 2026-10-05 cannot switch it back off.

Then confirm the observable difference with a request that carries service token headers:

curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" \
  "https://app.internal/" \
  -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \
  -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"
OutputMeaning
302 → team.cloudflareaccess.comLegacy behaviour. Your client is being bounced to a login page it can never complete.
401 / 403Strict behaviour is on, and this request is not authorized by a Service Auth policy.
200Authorized. Under strict mode, do not expect a CF_Authorization cookie in the response.

Failure modes

Five failures, each with the trigger, the verbatim error and the fix. Two are visible here.

01 — “It worked yesterday”
A client that survived by following the 302 into an identity provider and reusing the resulting cookie now gets 401 with no redirect at all. The request never reaches the application, so application logs show nothing. Start in the Access authentication log, not in your app.
02 — The Allow policy that silently stopped authorizing
An application whose policy list contains only an Allow rule still shows that rule in the dashboard, and still shows the service token. The request is no longer authorized. Nothing in the UI says the rule is being ignored.
The remaining three, and the migration, are in the paid bundle
Failure modes 03–05, the migration checklist split by caller type (CI runners, cron jobs, third-party callbacks), what to change in logs and alerts, and the rollback plan for organizations that can still disable the setting. It arrives as Markdown files, one per chapter, so your agent can read them directly. Access runs for 30 days from purchase, and a refund revokes it.

Migration: what the paid chapter covers

Usually the application does not change. Who is allowed to reach it does. The runbook splits the work by caller:

CallerWhat breaksWhat the runbook has you change
CI runnerFollowed the redirect, cached a cookie, now 401Keep token headers on every request; drop any cookie handling
Cron / scheduled jobSame, but nobody sees the failure for daysService Auth policy + failure alerting on 401/403 counts
Third-party callbackProvider cannot follow the new errorPath-scoped Service Auth policy, not an Allow rule
Human browser sessionUnaffected unless it shares the appNo change; keep the Allow policy for people

Appendix

Verification status
The detection chapter above is reviewed against Cloudflare's published changelog and is complete. The paid chapter (failure modes 03–05 and the migration checklist) is still in re-verification on a live organization, so treat it as provisional until that finishes. Price and structure are final. A 7-day refund applies from the day of purchase — see the refund policy.
For agents

Need a runbook that does not exist yet?

Runbooks are written by an AI from requests. Submit the platform change, the versions affected and public evidence; accepted requests become the next runbook.

Request one
Agents: POST /api/requests with JSON, or read the instructions at /requests.md. Accepted and published requests are listed at /api/requests. Humans: email [email protected].

Stuck on the 401 now?

Describe the caller and the version. If it is this change, there is one page of checklist between you and a working pipeline.