Skip to content

Changelog

New updates and improvements at Cloudflare.

Set custom validity windows for RealtimeKit auth tokens

RealtimeKit auth tokens now support custom validity windows, and you can revoke a single token. When your backend adds a participant to a meeting, it gets back an auth token that the participant's app uses to join.

Previously, every token was valid for 100 days from the moment it was issued. Now you can choose when a token starts and stops working, for example only during a scheduled class or interview, so a shared link stops working once the session is over. Pass not_before and expires_on in the token object when you add a participant:

Required API token permissions

At least one of the following token permissions is required:
  • Realtime Admin
  • Realtime
Add a participantbash
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/realtime/kit/$APP_ID/meetings/$MEETING_ID/participants" \
	--request POST \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"name": "Mary Sue",
		"preset_name": "<preset_name>",
		"custom_participant_id": "<uuid_of_the_user_in_your_system>",
		"token": {
				"not_before": "2026-12-01T15:00:00Z",
				"expires_on": "2026-12-01T17:00:00Z"
		}
	}'

Both fields are optional, so existing integrations keep getting 100-day tokens.

You can also revoke a single token without setting the whole meeting to INACTIVE. If the participant is in the meeting, RealtimeKit removes them. A revoked token can take up to 60 seconds to stop working everywhere, so delete the participant instead if you need to block them immediately.

RealtimeKit rejects expired, not yet valid, and revoked tokens before the participant enters the meeting, so you are not billed for them.

Learn more

Add noise cancellation to web apps built on RealtimeKit

You can now add noise cancellation to RealtimeKit web apps with the new @cloudflare/realtimekit-noise-cancellation package. RealtimeKit is a high-level SDK for adding real-time audio and video components, such as video meetings, to your web or mobile app.

Install the package:

npm i @cloudflare/realtimekit-noise-cancellation

After you initialize the meeting, pass it to init():

import { RealtimeKitNoiseCancellation } from "@cloudflare/realtimekit-noise-cancellation";

// Enables automatically when the mic is available, without delaying join.
void RealtimeKitNoiseCancellation.init({ meeting }).catch(console.warn);

How it works

  • Filters background noise in the participant's browser, before their audio is sent to the meeting.
  • Turns on automatically after init(), as soon as the participant's microphone is on.
  • Keeps running through mute, unmute, and reconnects, and cleans up when the participant leaves.
  • Never unmutes the microphone.

Noise cancellation works in React, Angular, and JavaScript apps on Chrome, Edge, Firefox, and Safari, including mobile browsers. The RealtimeKit iOS and Android SDKs do not yet support it.

Learn more

New hash functions — sha1(), md5(), and sha512()

Cloudflare Rules supports three new hash functions: sha1(), md5(), and sha512(). Use them to compute hashes for systems that require these algorithms.

Like the existing sha256() function, each accepts a string or byte array and returns raw bytes:

Function Algorithm Output length
md5() MD5 16 bytes
sha1() SHA-1 20 bytes
sha512() SHA-512 64 bytes

For example, combine sha512() with encode_base64() to produce a Base64-encoded hash:

encode_base64(sha512("hello world"))

For details, refer to the sha1(), md5(), and sha512() function references.

Cloudflare Tunnel extends URL normalization

Starting from version 2026.11.0, Cloudflare Tunnel extends the URL normalization introduced in 2026.10.0. Normalization now handles semicolon-delimited path parameters before matching ingress rules. This improves security for tunnels with rules that require Cloudflare Access validation. The URL path sent to your origin stays the same.

Starting 2027-02-08, new cloudflared releases will turn on URL normalization by default. This replaces the previously announced date of 2027-01-25, giving you time to test the updated behavior. Upgrade to version 2026.11.0 or later and test your path-based routing before that date, including rules that match paths containing semicolons. Configurations without rules requiring Access validation are unaffected.

This setting is currently off by default. To turn it on, run:

cloudflared tunnel --disable-path-normalization=false run <TUNNEL_NAME_OR_UUID>

Alternatively, set TUNNEL_DISABLE_PATH_NORMALIZATION=false on each cloudflared replica and restart it.

For more information, refer to ingress matching and Access validation at the origin.

GitHub automatically detects leaked Access service tokens

GitHub secret scanning automatically detects Cloudflare Access service token secrets exposed in public repositories and reports them to Cloudflare. Access then disables the affected token and emails account administrators.

Other secret scanning tools can identify Access service tokens using their consistent Client Secret format: cfast_, followed by 40 alphanumeric characters and an eight-character hexadecimal checksum. For tools that support custom detection rules, use this regular expression to find possible secrets:

cfast_[A-Za-z0-9]{40}[a-f0-9]{8}

This pattern applies to Client Secrets created on or after August 26, 2026, not legacy 64-character hexadecimal secrets. Matching the pattern does not validate the checksum or confirm that the secret is active. For details, refer to Client Secret format.

Recover a leaked service token

Before you can re-enable a leaked token, you must rotate its secret.

Leaked secrets do not support a rotation grace period. When you rotate one, the previous secret is discarded immediately. Update your services with the new secret, then re-enable the token.

For API rotations, omit previous_client_secret_expires_at. A future expiration returns 400. Attempting to re-enable the token before rotation returns 409.

Leaked service token rotation dialog warning that the current secret is revoked immediately and the token remains disabled.

For recovery steps and leak metadata fields, refer to Recover a leaked service token.

Prioritize Web Assets operations with metric views

The Web Assets > Operations page now includes metric-focused views for traffic, errors, latency, response size, and security. Each view surfaces the relevant metrics and supports server-side sorting, making it easier to prioritize operations in large inventories.

Refer to Endpoint Management for more information about managing and analyzing operations.

Improved Request Routing to Durable Objects

Cloudflare has reduced the number of round trips needed to connect to a Durable Object when a location lookup follows a forwarding record to another data center.

When an object's destination isn't cached in Cloudflare's network, the first data center contacted may have a forwarding record pointing to another data center.

Previously, the first data center acquired a connection to the object at the destination and proxied it back to the caller. The caller then established its own direct connection to the object.

Now, the first data center returns the destination directly, without first acquiring a connection to the object. The caller then establishes a direct connection, avoiding the intermediate connection and duplicate acquisition.

Skipping this intermediate connection can reduce p99 connection latency for these relocation-related requests. Actual results depend on your workload and traffic patterns.

No code or configuration changes are required to benefit from this improvement.

To learn more about how Workers connect to Durable Objects, refer to Durable Object namespaces.

Hyperdrive raises limits for connections and configurations

Customers on a Workers Paid plan can now create up to 100 Hyperdrive configurations, up from 25, and configure up to 1,500 origin database connections per configuration, up from 100.

Configuration limit

The configuration limit is the maximum number of Hyperdrive configurations you can create per account. Workers Paid customers can now create up to 100 configurations, allowing more workloads to take advantage of connection pooling and query caching across different databases.

Origin connection limit

The origin connection limit is the maximum number of database connections that Hyperdrive can make to your origin database per configuration. Workers Paid customers can now configure up to 1,500 origin connections, increasing the connection pool size available for workloads that need more concurrent database access. You can configure this value via the dashboard, Wrangler, or the REST API.

We recommend setting the origin connection limit lower than your origin database's connection limit.

For more information, refer to Hyperdrive limits and Tune connection pooling.

Add a collaborative whiteboard to meetings built on RealtimeKit

You can now add a collaborative whiteboard to RealtimeKit meetings with the Whiteboard plugin, which Cloudflare hosts and runs for you. RealtimeKit provides SDKs for running live audio and video meetings in your app. Many companies use it today to run online education and interview platforms, where participants often need a shared whiteboard to work through ideas together.

You add the Whiteboard plugin with the same plugins API you use for your own plugins. Load it in an iframe, with the participant's auth token after # in the URL:

const WHITEBOARD_URL = "https://whiteboard-v2.plugins.realtime.cloudflare.com/";

function createWhiteboard(authToken: string): HTMLIFrameElement {
	const iframe = document.createElement("iframe");
	iframe.style.width = "100%";
	iframe.style.height = "100%";
	iframe.style.border = "none";
	// Lets participants copy and paste on the board.
	iframe.allow = "clipboard-read; clipboard-write";
	// The plugin does not need your page's address.
	iframe.referrerPolicy = "no-referrer";
	iframe.src = `${WHITEBOARD_URL}#authToken=${encodeURIComponent(authToken)}`;
	return iframe;
}

const whiteboardElement = createWhiteboard("<auth_token>");

Then pass whiteboardElement as the plugin's component when you initialize the SDK. The Whiteboard plugin guide has the registration code for web, Android, iOS, and React Native.

You can also build your own plugins and render them alongside the meeting UI. A whiteboard you build yourself needs a server that sends every stroke to every participant, saves the board between sessions, and checks who can open it. With the Whiteboard plugin, Cloudflare runs all of that for you.

How it works

  • Participants draw shapes, arrows, freehand strokes, and text on one shared board, and see each other's cursors and names.
  • Each meeting has one board. It stays the same across sessions, so participants pick up where they left off.
  • The plugin checks each participant's auth token, so only participants in the meeting can open its board.
  • It works on any domain, and you do not need to register your app's origin.

Learn more

Send custom API headers with Wrangler and Cloudflare CLI

Wrangler 4.160.0 and Cloudflare CLI (cf) 1.0.0-beta.29 support custom headers for Cloudflare API requests. Use CLOUDFLARE_API_HEADERS to add headers or override most generated values, with the exception of protected body and transport headers.

For example, to send X-Custom-Header: value, set:

export CLOUDFLARE_API_HEADERS='{"X-Custom-Header":"value"}'

Then run your Wrangler or cf command.

For usage and restrictions, refer to the Wrangler environment variable reference and Cloudflare CLI environment variable reference.

Serve a Worker's static assets from a URL path like /blog/

You can now serve your Worker's static assets from a URL path prefix, such as example.com/blog/, without changing your build output.

Previously, to serve assets from /blog/, you had to nest your files in a matching blog directory. Now, set assets.base_path in your Wrangler configuration file, or worker.assets.basePath in cloudflare.config.ts, and keep your files at the root of your asset directory.

Use Wrangler 4.148.0 ↗︎ or later. With cloudflare.config.ts, use cf 1.0.0-beta.13 ↗︎ or later.

For example, this configuration serves your built assets from /blog/:

cloudflare.config.tsts
import { defineConfig } from "cf/config";

export default defineConfig({
worker: {
  name: "blog",
  // Set this to today's date
  compatibilityDate: "2026-11-12",
  assets: {
    basePath: "/blog",
  },
},
});
{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "assets": {
    "directory": "./dist",
    "base_path": "/blog"
  }
}
[assets]
directory = "./dist"
base_path = "/blog"

Requests to /blog/ serve dist/index.html, and requests to /blog/posts/post1 serve dist/posts/post1.html. Requests outside /blog/ do not match your static assets and run your Worker, if it has one.

Paths in _headers, _redirects, and run_worker_first use the full public path, including /blog. If you build with the Cloudflare Vite plugin, also set Vite's base option to /blog/.

For more information, refer to Serving a subdirectory.

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.