Skip to content

Changelog

New updates and improvements at Cloudflare.

Cloudflare One Client for Windows (version 2026.9.2663.1)

A new Beta release for the Windows Cloudflare One Client is now available on the beta releases downloads page.

This release includes the following highlights:

  • Added automatic endpoint selection for Global Acceleration. When Global Acceleration is enabled for an organization, the client connects to the Global Acceleration endpoints while the device is in the acceleration region and to the standard anycast endpoints otherwise, and reconnects when a network change moves the device between them without requiring action from the user. The Connectivity page shows which tunnel and API endpoints are in use, and users who are allowed to override the selection can choose endpoints in Settings.
  • Added protection against unauthorized modification or uninstallation of the Cloudflare One Client. When enabled, the user will be asked to provide an administrator-generated code when trying to uninstall the client, which will otherwise be blocked. Users, including administrators, also can no longer stop the client service, and attempts to authorize an uninstall with a code or token, whether accepted or rejected, are reported to Cloudflare.
  • Added a Diagnostics page to the client that shows the connection status and health, live tunnel and device metrics, network details and the results of DEX tests in one place. Users can run a speed test from the page that compares performance inside and outside the tunnel while the client is connected. The Troubleshooting tools button collects a full warp-diag bundle, or runs a captive portal test that briefly reconnects Wi-Fi, and saves the result to the Desktop, so users no longer need to run warp-diag from a terminal.
  • The client now shows a banner when the network limits the tunnel MTU to a degraded or critically low value. The banner clears when the MTU recovers or the client disconnects.

Additional changes and improvements

  • The client now applies tunnel MTUs between 1147 and 1199 bytes measured by Path MTU Discovery. Previously the client ignored these values and kept a larger MTU, which could drop larger packets on networks such as mobile hotspots while the client showed as connected.
  • When Path MTU Discovery is enabled, the client now accepts larger packets from Cloudflare instead of limiting them to the size it uses for its own outbound packets.
  • When Path MTU Discovery measures an IPv6 path MTU below 1280 bytes, the client now reconnects over IPv4 and keeps preferring IPv4 until the network changes. Previously the client could stay on a smaller tunnel MTU over IPv6 on networks where IPv4 supports larger packets.
  • Access reauthentication requests now trust certificates in the operating system's certificate store, so reauthentication works on networks that perform TLS inspection.
  • For Zero Trust deployments, the client now records a traceroute of the network path outside the tunnel when the tunnel degrades or fails to connect. warp-diag includes the same trace.
  • warp-diag now includes redacted copies of the deployed MDM files and the names, but not the values, of stored registration secrets. It reports a QUIC path MTU only when one was measured.
  • Added the MDM parameters mdm_file_debounce_secs (1–60) and mdm_file_unavailable_debounce_secs (0–300), which set how long the client waits before applying a changed MDM file and before acting on a missing or unreadable one.
  • Added the MDM parameters managed_network_probe_interval_secs (30–300, default 30) and managed_network_probe_count (0 disables probing, 1–10, or -1 to keep probing until a managed network is found; default 1). After a registration or network change finds no managed network, the client now rechecks, so a device doesn't stay on the default profile because of a transient connection failure. Set the count to 0 to keep the previous behavior.
  • Added the multicast network policy and MDM setting (allow or drop, default drop). When set to allow, the client sends traffic for multicast addresses through the tunnel instead of dropping it, for networks that use multicast ranges for other traffic.
  • In proxy mode for Zero Trust, the client now sends hostnames from HTTP/HTTPS and SOCKS5 requests to Cloudflare for resolution instead of resolving them on the device.
  • The Connectivity page now shows the IPv4 and IPv6 addresses assigned to the tunnel while the client is connected.
  • When the app cannot reach the client service, the home screen now says why (service not running, not accepting connections, not responding, or connection dropped and reconnecting). It shows an error code and a Learn more link instead of "IPC error".
  • The client now shows a notification when an administrator removes the user's selected virtual network, and shows a specific message when the user selects a virtual network that is no longer available.
  • The consumer client home screen now shows when the connection is post-quantum encrypted.
  • warp-cli target list now accepts --hostname to filter targets by one or more comma-separated hostnames.
  • DEX HTTP tests now send a default User-Agent that identifies the Cloudflare One Client when the test does not configure one.
  • Reduced CPU usage by the Windows Capability Access Manager service (camsvc) caused by the client's Wi-Fi queries.
  • Reduced the client UI's memory usage.
  • The client UI no longer starts WMIC or PowerShell processes to collect memory information for crash reports.
  • Fixed installs failing with error 1603 on devices with Windows App Control (WDAC) policies, because some files inside the installer's custom actions were not signed. All components of the installer are now signed.
  • Fixed the installer asking the user to close running applications during an upgrade, downgrade or uninstall because other programs loaded the client's Visual C++ runtime libraries through the system PATH. The client now loads these libraries from a private folder so that closing other applications is unnecessary.
  • Fixed reinstalling the same version of the client from its MSI removing the updater service, which stopped the client from updating.
  • Fixed the client window appearing blank or white after an upgrade, at sign-in, after waking from sleep, or after a display change.
  • Fixed the client UI freezing and no longer showing status updates after the device woke from sleep.
  • Fixed the client UI looking for one of its libraries in a directory that standard users can create before looking in the installation directory.
  • Fixed a local user being able to crash the client service by sending a crafted query to the local DNS resolver.
  • Fixed the client service restarting when a firewall update for captive portal detection stalled while the device was asleep.
  • Fixed the client service leaking handles to processes after they exited, which could leave those processes listed as running.
  • Fixed the client getting stuck in a disconnected state on Windows on Arm devices because leftover tunnel adapters were not removed.
  • Fixed Windows resetting the Wi-Fi adapter after sign-in or a Wi-Fi restart when the client's firewall rules in Exclude split tunnel mode blocked Windows network connectivity checks. The client now allows those checks.
  • Fixed the client missing some network configuration changes after the first change was detected.
  • Fixed the client being unable to connect after an upgrade, downgrade, and upgrade that switched between consumer and Zero Trust registrations. The client now clears the mismatched registration so the user can register again.
  • Fixed the client continuing to use the previous tunnel protocol after a key rotation for a protocol change failed. The client now retries the rotation the next time it connects.
  • Fixed service token enrollment failing when it ran shortly after the service token was created. The client now retries while the new token becomes available.
  • Fixed the client reconnecting repeatedly when Global Acceleration automatic endpoint selection was enabled on devices in the acceleration region, and fixed the client keeping its previous data center after the selected endpoints changed.
  • Fixed a hostname-based split tunnel entry not taking effect until the next reconnect after its firewall rule failed to apply.
  • Fixed the client service failing to start when a split tunnel address in mdm.xml had no prefix length. A bare IP address is now treated as a single host.
  • Fixed a single malformed element in mdm.xml causing the client to ignore the whole file. warp-diag now includes the file as written.
  • Fixed warp-cli dns fallback add accepting an empty domain, which sent all DNS queries to the local resolver instead of Gateway. Fallback domain and split tunnel entries are now normalized, so removing an entry matches regardless of case or a trailing dot.
  • Fixed the DNS proxy caching answers for longer than the TTL of a CNAME record in the chain.
  • Fixed warp-cli registration license reporting an error on slow networks even though the license was applied, which left the client registered to a WARP+ account it did not recognize.
  • Fixed warp-cli debug network showing an all-zero interface GUID.
  • Fixed Digital Experience Monitoring (DEX) results being reported with timestamps offset from the actual time after the system clock was corrected.

Known issues

  • A Windows DNS client regression may cause connectivity check failures on systems containing large hosts files. While our client includes a mitigation for this issue, users may still experience reduced DNS performance and connectivity check failures.
  • After an administrator removes a virtual network from a device profile or changes its default network, the virtual network list in the client may continue to show the previous networks until the client is restarted. This is a display issue only: the device connects to the networks its profile allows, and selecting a removed network is rejected without changing the connection. The warp-cli vnet command shows the current list. This will be addressed prior to the next GA release.

Cloudflare One Client for macOS (version 2026.9.2663.1)

A new Beta release for the macOS Cloudflare One Client is now available on the beta releases downloads page.

This release includes the following highlights:

  • macOS 15.0 is now the minimum supported version. This release does not run on macOS 14.
  • Added automatic endpoint selection for Global Acceleration. When Global Acceleration is enabled for an organization, the client connects to the Global Acceleration endpoints while the device is in the acceleration region and to the standard anycast endpoints otherwise, and reconnects when a network change moves the device between them without requiring action from the user. The Connectivity page shows which tunnel and API endpoints are in use, and users who are allowed to override the selection can choose endpoints in Settings.
  • Added a Diagnostics page to the client that shows the connection status and health, live tunnel and device metrics, network details and the results of DEX tests in one place. Users can run a speed test from the page that compares performance inside and outside the tunnel while the client is connected. The Troubleshooting tools button collects a full warp-diag bundle, or runs a captive portal test that briefly reconnects Wi-Fi, and saves the result to the Desktop, so users no longer need to run warp-diag from a terminal.
  • The client now shows a banner when the network limits the tunnel MTU to a degraded or critically low value. The banner clears when the MTU recovers or the client disconnects.

Additional changes and improvements

  • The client now applies tunnel MTUs between 1147 and 1199 bytes measured by Path MTU Discovery. Previously the client ignored these values and kept a larger MTU, which could drop larger packets on networks such as mobile hotspots while the client showed as connected.
  • When Path MTU Discovery is enabled, the client now accepts larger packets from Cloudflare instead of limiting them to the size it uses for its own outbound packets.
  • When Path MTU Discovery measures an IPv6 path MTU below 1280 bytes, the client now reconnects over IPv4 and keeps preferring IPv4 until the network changes. Previously the client could stay on a smaller tunnel MTU over IPv6 on networks where IPv4 supports larger packets.
  • Access reauthentication requests now trust certificates in the operating system's certificate store, so reauthentication works on networks that perform TLS inspection.
  • For Zero Trust deployments, the client now records a traceroute of the network path outside the tunnel when the tunnel degrades or fails to connect. warp-diag includes the same trace.
  • warp-diag now includes redacted copies of the deployed MDM files and reports a QUIC path MTU only when one was measured.
  • Added the MDM parameters managed_network_probe_interval_secs (30–300, default 30) and managed_network_probe_count (0 disables probing, 1–10, or -1 to keep probing until a managed network is found; default 1). After a registration or network change finds no managed network, the client now rechecks, so a device doesn't stay on the default profile because of a transient connection failure. Set the count to 0 to keep the previous behavior.
  • Added the multicast network policy and MDM setting (allow or drop, default drop). When set to allow, the client sends traffic for multicast addresses through the tunnel instead of dropping it, for networks that use multicast ranges for other traffic.
  • In proxy mode for Zero Trust, the client now sends hostnames from HTTP/HTTPS and SOCKS5 requests to Cloudflare for resolution, instead of resolving them on the device.
  • The Connectivity page now shows the IPv4 and IPv6 addresses assigned to the tunnel while the client is connected.
  • When the app cannot reach the client service, the home screen now says why (service not running, not accepting connections, not responding, or connection dropped and reconnecting). It shows an error code and a Learn more link instead of "IPC error".
  • The client now shows a notification when an administrator removes the user's selected virtual network, and shows a specific message when the user selects a virtual network that is no longer available.
  • The consumer client home screen now shows when the connection is post-quantum encrypted.
  • warp-cli target list now accepts --hostname to filter targets by one or more comma-separated hostnames.
  • DEX HTTP tests now send a default User-Agent that identifies the Cloudflare One Client when the test does not configure one.
  • The client's background services now start only when their binaries are signed by Cloudflare, so replacing the application bundle cannot run other code with the services' privileges.
  • Reduced the client UI's memory usage on the home screen.
  • Fixed a managed registration being removed when the MDM configuration file was briefly missing or unreadable. The client now keeps the last applied policy for 20 seconds after the file becomes unavailable. The new MDM parameters mdm_file_debounce_secs (1–60) and mdm_file_unavailable_debounce_secs (0–300) change how long the client waits before applying a changed file and before acting on a missing one.
  • Fixed an upgrade sometimes leaving the client without a running service when the previous service was slow to stop. The installer now waits up to 10 seconds for the old service to be removed before starting the new one.
  • Fixed the client UI not showing onboarding on first launch while a notification permission request was pending.
  • Fixed the client UI crashing when the Mac woke from sleep or a display configuration changed.
  • Fixed the client UI freezing and no longer showing status updates after the Mac woke from sleep.
  • Fixed DNS queries failing for a short time after the Mac woke from sleep. The client now replaces stale connections to the DNS resolver during its wake connectivity check.
  • Fixed the client continuing to use the previous tunnel protocol after a key rotation for a protocol change failed. The client now retries the rotation the next time it connects.
  • Fixed service token enrollment failing when it ran shortly after the service token was created. The client now retries while the new token becomes available.
  • Fixed the client reconnecting repeatedly when Global Acceleration automatic endpoint selection was enabled on devices in the acceleration region, and fixed the client keeping its previous data center after the selected endpoints changed.
  • Fixed a hostname-based split tunnel entry not taking effect until the next reconnect after its firewall rule failed to apply.
  • Fixed split tunnel updates for hostname-based entries failing when the client tried to remove a route that macOS had not installed.
  • Fixed warp-cli dns fallback add accepting an empty domain, which sent all DNS queries to the local resolver instead of Gateway. Fallback domain and split tunnel entries are now normalized, so removing an entry matches regardless of case or a trailing dot.
  • Fixed the DNS proxy caching answers for longer than the TTL of a CNAME record in the chain.
  • Fixed warp-cli registration license reporting an error on slow networks even though the license was applied, which left the client registered to a WARP+ account it did not recognize.
  • Fixed Digital Experience Monitoring (DEX) results being reported with timestamps offset from the actual time after the system clock was corrected.
  • Fixed the OS version detail stored for a device keeping an outdated value, including the text "Usage: sw_vers…" reported by client versions 2023.5.587.1 through 2024.12.760.0. The client now clears the value the next time it connects.

Known issues

  • After an administrator removes a virtual network from a device profile or changes its default network, the virtual network list in the client may continue to show the previous networks until the client is restarted. This is a display issue only: the device connects to the networks its profile allows, and selecting a removed network is rejected without changing the connection. The warp-cli vnet command shows the current list. This will be addressed prior to the next GA release.

Evaluate Flagship feature flags from Rust

Flagship now has an official Rust SDK. Use it to evaluate feature flags from async Rust server applications through OpenFeature, with the same targeting rules and percentage rollouts as the other Flagship SDKs.

Install the cloudflare-flagship ↗︎ crate:

cargo add cloudflare-flagship

Then register the provider and evaluate a flag:

let options = FlagshipClientOptions::builder()
    .app_id("<APP_ID>")
    .account_id("<ACCOUNT_ID>")
    .auth_token("<API_TOKEN>")
    .build()?;

let mut api = OpenFeature::default();
api.set_provider(FlagshipServerProvider::new(options)?).await;

let context = EvaluationContext::default().with_targeting_key("user-42");
let enabled = api
    .create_client()
    .get_bool_value("new-checkout", Some(&context), None)
    .await
    .unwrap_or(false);

The provider evaluates flags over HTTP by default. Turn on local evaluation to download flag definitions and evaluate flags in-process, without a network request per evaluation. The SDK also supports structured evaluation context, an optional response cache, and logging and telemetry hooks.

The SDK requires Rust 1.88 or later and a Tokio runtime. For setup and configuration options, refer to the Rust SDK documentation.

Faster MP4 downloads from Cloudflare Stream

Generating MP4 downloads from Cloudflare Stream is now up to 40% faster, with no changes to your implementation required. This improvement is most impactful for on-demand videos over 1 minute in duration.

You can generate an MP4 download in the Dashboard, with the cf, the Cloudflare CLI CLI, or by sending a POST request.

cf clish
cf stream videos downloads create default --identifier "$VIDEO_UID"
Create downloadbash
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/stream/$IDENTIFIER/downloads/default" \
	--request POST \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

Both of these response include the download URL and processing progress:

{
	"result": {
		"default": {
			"status": "inprogress",
			"percentComplete": 75.0,
			"url": "https://customer-<CODE>.cloudflarestream.com/<VIDEO_UID>/downloads/default.mp4"
		}
	},
	"success": true,
	"errors": [],
	"messages": []
}

For more information, refer to Generate downloadable MP4 files.

Workers Builds and Pages now list GitHub repositories based on your GitHub account

When you connect a GitHub repository to Workers Builds or Pages, the accounts and repositories you can pick from are now based on your own GitHub account, so the list reflects the repositories you work with on GitHub. Previously, the list was based on the Cloudflare Workers & Pages GitHub App installations linked to your Cloudflare account, so it could include repositories that you cannot access on GitHub.

Three developers on the same Cloudflare account have all authorized the app, and the app is installed on acme-corp and dev-1. Each sees a different repository picker. dev-1 can pick acme-corp or dev-1, with payments-api and website listed for acme-corp. dev-2 can only pick acme-corp, with only website listed. dev-3 has no accounts or repositories, only the option to add a GitHub account.

The list now shows:

  • Your own GitHub account, if the app is installed on it.
  • GitHub organizations that have the app installed, where you can access at least one repository.
  • The repositories you can access in each of them.

GitHub accounts that belong to other users are no longer listed, even if they have given you access to one of their repositories.

What this means for you:

Authorizing the app and installing it are two separate steps on GitHub. For more details, refer to Install and authorize the app for Workers Builds and Pages.

Authorize: tells Cloudflare who you are, once per person, listed under Authorized GitHub Apps. Install: decides which repositories Cloudflare can access, listed under Installed GitHub Apps.
  • If you have already authorized the app with your GitHub user: Nothing changes. You can check on the Authorized GitHub Apps page ↗︎ on GitHub.
  • If you have not: The next time you connect a repository, Cloudflare sends you to GitHub to authorize the app. You only need to do this once, even if someone else on your Cloudflare account already connected GitHub.
  • If the app is not installed on any GitHub account you can access: After you authorize, install the app on your own GitHub account or an organization, the same as before.
  • If an account or organization is missing from the list: Select Add GitHub account and install the app on it.

Projects that are already connected to a repository are not affected and keep building.

For more information, refer to Repository access for Workers Builds and Pages.

Set a concurrency limit for each Workflow

You can now set a concurrency limit on an individual Workflow to cap how many of its instances run at the same time. Use it to protect a database or third-party API that slows down or rejects requests past a certain number of concurrent connections, or to distribute load more evenly across your Workflows so that one high-volume Workflow does not use all of your account's concurrency.

For example, to allow only 10 instances of a Workflow to run at a time, set concurrency.limit on its workflows binding and redeploy:

{
	"workflows": [
		{
			"name": "my-workflow",
			"binding": "MY_WORKFLOW",
			"class_name": "MyWorkflow",
			"concurrency": {
				"limit": 10,
			},
		},
	],
}
[[workflows]]
name = "my-workflow"
binding = "MY_WORKFLOW"
class_name = "MyWorkflow"

  [workflows.concurrency]
  limit = 10

You can also set concurrency on a Workflow declared in exports, or with exports.workflow() in @cloudflare/config.

Instances above the limit are not rejected. They are queued and start automatically as running instances finish or move to the waiting state.

The limit must be a positive integer, and cannot be higher than your account's concurrency limit (100 on Workers Free, 50,000 on Workers Paid). Lowering the limit does not stop instances that are already running. Workflows without a concurrency limit can still use up to your account's full concurrency limit.

Per-Workflow concurrency limits require Wrangler 4.127.0 or above.

For more information, refer to Concurrency limits.

Run the Codex agent loop on Cloudflare Workers

Run the Codex agent loop in a Cloudflare Durable Object with this experimental Agents SDK example ↗︎. Conversations, files, and completed model and tool results persist across restarts, allowing the agent to recover after interruptions.

The example adapts Codex’s Rust turn-processing code ↗︎ to WebAssembly and uses Agents SDK capabilities for storage and recovery.

The harness combines Agents SDK capabilities for durable execution:

  • Tasks journals model calls and tool execution. Completed steps reuse their recorded results after a restart. Interrupted steps can run again.
  • Sessions stores conversation history and compacts the model context.
  • Streams stores ordered events for replay after reconnecting.
  • Workspace provides tools to read and write persistent files.

For example, use OpenAI's GPT-6.1 Sol through AI Gateway. Configure the model with createAI and install the capabilities on a Durable Object:

import { DurableObject } from "cloudflare:workers";
import { Workspace } from "@cloudflare/computer";
import { Lifecycle } from "agents/lifecycle";
import { createAI } from "agents/models/ai-sdk";
import { Sessions } from "agents/sessions";
import { Streams } from "agents/streams";
import { Tasks } from "agents/tasks";
import { CodexHarness } from "./codex-harness";

export class Coder extends DurableObject {
	tasks = new Tasks();
	streams = new Streams();
	sessions = new Sessions();
	workspace = new Workspace({ storage: this.ctx.storage });

	codex = new CodexHarness({
		tasks: this.tasks,
		streams: this.streams,
		sessions: this.sessions,
		workspace: this.workspace,
		model: createAI({ binding: this.env.AI, id: "default" })(
			"openai/gpt-6.1-sol",
		),
	});

	lifecycle = Lifecycle.install(this)
		.use(this.tasks)
		.use(this.streams)
		.use(this.sessions)
		.use(this.codex);
}
import { DurableObject } from "cloudflare:workers";
import { Workspace } from "@cloudflare/computer";
import { Lifecycle } from "agents/lifecycle";
import { createAI } from "agents/models/ai-sdk";
import { Sessions } from "agents/sessions";
import { Streams } from "agents/streams";
import { Tasks } from "agents/tasks";
import { CodexHarness } from "./codex-harness";

export class Coder extends DurableObject<Env> {
	tasks = new Tasks();
	streams = new Streams();
	sessions = new Sessions();
	workspace = new Workspace({ storage: this.ctx.storage });

	codex = new CodexHarness({
		tasks: this.tasks,
		streams: this.streams,
		sessions: this.sessions,
		workspace: this.workspace,
		model: createAI({ binding: this.env.AI, id: "default" })("openai/gpt-6.1-sol"),
	});

	lifecycle = Lifecycle.install(this)
		.use(this.tasks)
		.use(this.streams)
		.use(this.sessions)
		.use(this.codex);
}

To use this model, configure the default gateway with Unified Billing or a stored OpenAI API key.

For setup, models, tools, and recovery behavior, refer to the Codex harness guide.

Run Exo agents on Cloudflare

You can now run Exo agents on Cloudflare, with Durable Objects coordinating conversations and Cloudflare Sandboxes running Linux tools. Define an agent in Markdown, then use Exo's CLI or HTTP API to run it.

After deploying the Cloudflare adapter and configuring your Exo provider ↗︎, add an openai vault credential and save this definition as agent.md:

---
harness: basic
model:
  name: gpt-6.1-sol
  credential: openai
---

Help the user with their task.

Run the agent against your Cloudflare deployment with Exo's CLI:

exo --provider cloudflare agent run --agent-file agent.md

The Exo project maintains the Cloudflare adapter independently of Cloudflare. It does not require the Agents SDK.

Follow the Exo guide for architecture, recovery behavior, and upstream setup instructions.

Run the Nanocode agent harness in Cloudflare Durable Objects

You can now run Nanocode ↗︎ coding agents in Cloudflare Durable Objects, with persistent session history and recovery after interruptions.

Nanocode's Rust engine runs as WebAssembly and implements Codex and Claude Code prompt and tool conventions. Its Cloudflare host saves turn progress and tool results in SQLite and uses alarms to resume pending work. The Nanocode project maintains the host independently of Cloudflare; it does not require the Agents SDK.

Start with the reference Worker ↗︎ and follow Nanocode on Workers for setup, models, and recovery limits.

Partitioned cookie support for Bot Management

Cloudflare now adds the Partitioned attribute to the __cf_bm cookie on compatible HTTPS requests. The attribute is added only when the cookie can also be issued with SameSite=None and Secure.

When users access your content through an <iframe> on another site, the browser handles __cf_bm as a third-party cookie. Browser privacy controls may block third-party cookies. Adding Partitioned allows the __cf_bm cookie to persist within that top-level site. This means that Bot Management can preserve continuity across requests, even when your content is embedded on another site.

For more information, refer to Cloudflare cookies.

Improved Durable Object Startup Placement

Cloudflare has improved how it chooses where to start a Durable Object after the object has been inactive.

Reactivated Durable Objects now start on the machine that last ran them whenever possible, so their data doesn't need to be loaded again.

This can make cold starts less frequent for SQLite-backed Durable Objects that are reactivated soon after going idle. Actual results depend on your workload and traffic patterns.

The change is live in all regions. No action is needed by customers to see benefits from this change.

To learn more about how Durable Objects are placed, refer to Data location.

Improved investigation search for Email security

Email security now has a unified search bar for investigations. It replaces the Email Screener side modal and makes searches easier to refine.

Search with keywords or field:value filters. Autocomplete suggests filters and values as you type. Add terms and press Enter to refine results, or select From, To, Disposition, Status, or Threat type values in results. Narrow results with a date preset or custom range.

The Email Security investigation search bar displays suggestions for disposition, status, threat type, sender, recipient, and other filters

This feature is available to all Email security customers.

Markdown for Agents analytics and tracing

Markdown for Agents is generally available, with new tools to monitor conversions and investigate partial or failed output.

In the Cloudflare dashboard, select your zone and go to Agent Readiness > Markdown for Agents:

  • Analytics shows conversion outcomes, estimated token reduction, top converted pages, top user agents, failure reasons, content limits, and pages with partial or failed conversions.
  • Logs provides sampled conversion events with outcome, failure reason, and content-limit filters.
  • Playground requests Markdown for a page on your zone and compares it with HTML. Inspect the Markdown, preview, response headers, and estimated token reduction.
Markdown for Agents dashboard showing conversion totals, full conversion rate, estimated token reduction, and conversions over time.

The GraphQL Analytics API exposes the same analytics through markdownForAgentsAdaptiveGroups at zone and account scope. Query conversion totals, outcomes, estimated token savings, and page diagnostics over the last seven days. Counts are sample-weighted estimates. Token savings use byte-based estimates from full conversions, not tokenizer counts.

Cloudflare Traces includes a markdown_conversion span for sampled streaming conversions. Inspect conversion outcomes, input and output bytes, converter CPU time, and content-limit flags alongside the rest of the request timeline.

For details and a GraphQL query example, refer to the Markdown for Agents documentation.

Redesigned Bots Directory on Cloudflare Radar, now powered by BotBase

The Cloudflare Radar Bots Directory ↗︎ now uses BotBase, Cloudflare's catalog of the bots and agents it tracks, and has a new design matching the Radar homepage.

Animation filtering the Bots Directory and opening the Cloudflare Crawler bot page, with its Identity and Traffic sections

Each bot page has a new Identity section showing the bot's access level, content use, Web Bot Auth verification, and user agents. Bot operators are also searchable from the Radar site search.

API

The List bots and Get bot details endpoints now describe each bot with:

  • categories: a bot can now have more than one category. Categories follow BotBase's groups, which add COMMERCE, and some older categories are now part of broader groups.
  • accessLevel: DIRECT if the bot reaches websites under its own identity, or INTERMEDIARY if it acts on behalf of another agent or a person.
  • contentUse: full if the content it fetches is kept and reused (for example, for model training or a search index), reference if it is cited or linked back to the source, or immediate if it is used once to answer a user's request.
  • documentationUrl and operatorWebsiteUrl (bot details only).

category and operatorUrl are deprecated in favor of categories and documentationUrl.

Visit the Bots Directory ↗︎ on Cloudflare Radar.

Review provider key activity in AI Gateway

AI Gateway now shows usage activity for your stored provider keys. Use this information to review credentials for rotation or removal.

In Provider Keys, keys are grouped by provider with masked previews, aliases, and last-used and last-updated dates. The Key security section highlights keys with recorded activity older than 90 days. You can review these keys and delete them after checking their dependencies.

Usage tracking starts November 2026.

For details on storing, rotating, and removing provider keys, refer to Bring your own keys.

Sign in to Cloudflare Access with passkeys

Cloudflare Access supports passkeys as a login method for protected applications and the App Launcher. Users can sign in with a passkey saved on their device, security key, or password manager instead of entering a one-time PIN or configuring an identity provider.

Users verify their identity with an existing login method once before enrolling a passkey. Administrators choose which applications accept passkeys and can remove a user's registered passkeys. Access policies still determine whether a user can access an application.

Passkeys identity-provider settings with automatic browser prompts turned on.

For setup and enrollment instructions, refer to Passkeys.

Cloudflare One adds fast flux detection to UEBA

Cloudflare One now includes fast flux detection as a predefined risk behavior for user and entity behavior analytics (UEBA). When enabled, detections contribute to a user's risk score.

Fast flux is a DNS technique that rapidly changes the IP addresses returned for a domain. Threat actors can use it to make malicious infrastructure harder to track and take down. Detecting it can help security teams identify potentially risky activity and investigate it sooner.

To turn on fast flux detection, go to Risk score > Risk behaviors in the Cloudflare Zero Trust dashboard.

Fast flux detection is available on Enterprise plans.

For more information, refer to User risk score.

User API tokens have a redesigned creation experience

User API tokens now use a redesigned dashboard experience that more closely matches Account API tokens, making it easier to create and review user-owned credentials while preserving their user-scoped behavior.

Redesigned User API token creation flow

What's new

  • A more consistent creation flow: User API tokens now follow the same modern dashboard pattern as Account API tokens, including a clearer create and review experience.
  • Improved policy editing: Policies are now easier to read and manage, with inline controls to add, edit, and remove policy blocks before creating the token.
  • Clearer restrictions during setup: Expiration presets and client IP address filtering are built directly into the creation flow so you can review token restrictions in one place.

These tokens still act on behalf of the creating user, even though the dashboard experience is now more consistent with Account API tokens. For more information, refer to Create API token, Create tokens via API, and Account API tokens.

Automatic retries for Durable Object calls

The runtime now retries fetch() and RPC calls to a Durable Object when they fail with a retryable error before reaching it. This applies whether the caller is a Worker or another Durable Object. Short disruptions, such as brief network interruptions, no longer need a retry loop in your code.

By default, the runtime retries a call up to four times, and starts no retry more than 10 seconds after the initial call starts. It does not retry errors thrown by your Durable Object code, or errors with .overloaded set to true.

If the connection drops and the runtime cannot tell whether the Durable Object received the call, it still retries, but the Durable Object rejects the retry if the first attempt arrived. A method never runs twice because of a retry, unless you mark it with retryable() from cloudflare:durable-objects:

src/index.jsjs
import { DurableObject } from "cloudflare:workers";
import { retryable } from "cloudflare:durable-objects";

export class Cart extends DurableObject {
	static {
		retryable(this.prototype.setQuantity);
	}
	// Idempotent: a second run sets the same quantity.
	async setQuantity(itemId, quantity) {
		await this.ctx.storage.put(itemId, quantity);
	}

	// Not retryable: a second run would add another item.
	async addOne(itemId) {
		const quantity = (await this.ctx.storage.get(itemId)) ?? 0;
		await this.ctx.storage.put(itemId, quantity + 1);
	}
}
src/index.tsts
import { DurableObject } from "cloudflare:workers";
import { retryable } from "cloudflare:durable-objects";

export class Cart extends DurableObject {
	static {
		retryable(this.prototype.setQuantity);
	}
	// Idempotent: a second run sets the same quantity.
	async setQuantity(itemId: string, quantity: number): Promise<void> {
		await this.ctx.storage.put(itemId, quantity);
	}

	// Not retryable: a second run would add another item.
	async addOne(itemId: string): Promise<void> {
		const quantity = (await this.ctx.storage.get<number>(itemId)) ?? 0;
		await this.ctx.storage.put(itemId, quantity + 1);
	}
}

To change the limits for one stub, pass a retry option to get() or getByName(). maxRetries accepts 0 to 10 retries, and timeoutMs accepts 500 to 60,000 milliseconds:

src/index.jsjs
const stub = env.CART.getByName("user-123", {
	retry: { maxRetries: 1, timeoutMs: 2000 },
});
src/index.tsts
const stub = env.CART.getByName("user-123", {
	retry: { maxRetries: 1, timeoutMs: 2000 },
});

If you already retry Durable Object calls in your own code, each of your attempts now includes the runtime's retries. Lower your own attempt count, or set maxRetries: 0 on stubs where your code handles retries.

To use retryable() and the retry option, update to Wrangler 4.158.0 or later.

For more information, refer to Automatic retries.