Monetization Gateway is now available in closed beta. Sellers can use it to charge agents for access to APIs, Model Context Protocol (MCP) tools, sites, and datasets.
Sellers (domain owners) define which requests require payment, the cost, and where the payment should be sent. Buyers receive the payment instructions, sign an authorization, and receive the resource after the payment has been settled. The Monetization Gateway uses the x402 protocol to handle payment authorization within the HTTP request flow.
The adapter connects live calls to any server that accepts WebSockets, such as a Durable Object. It delivers uncompressed pulse-code modulation (PCM) audio and JPEG video frames. Your backend can process this media without implementing a WebRTC client.
What you can build
Transcribe or record call audio, or let a voice agent hear and respond to participants. The AI audio example uses Durable Objects and Workers AI for transcription and speech generation. Separate adapters receive PCM audio and send generated speech back to participants.
Analyze images or build previews from live video. The WebRTC-to-JPEG example ↗︎ sends a browser's camera stream to a Durable Object as JPEG frames at one frame per second by default.
What changes for existing integrations
Existing adapter creation requests and media formats stay the same.
For WebRTC-to-WebSocket streaming, the SFU now automatically retries the same endpoint for up to 15 seconds instead of 5, with no additional API setting.
The close API is now idempotent and returns success even if the adapter has already closed:
This release introduces new detections to enhance protection against a specific GitLab path traversal vulnerability, alongside advanced generic rules targeting HTTP request smuggling, directory traversal, and command injection attempts.
Key Findings
CVE-2026-85706: A path traversal vulnerability affecting GitLab.
Ruleset
Rule ID
Legacy Rule ID
Description
Previous Action
New Action
Comments
Cloudflare Managed Ruleset
N/A
Broken Access Control - Directory Traversal
Log
Block
This is a new detection.
Cloudflare Managed Ruleset
N/A
HTTP Request Smuggling - Request Body Anomaly - Beta
Log
Block
This rule is merged into the original rule "HTTP/2 Request Smuggling - Request Body Anomaly" (ID: ).
Cloudflare Managed Ruleset
N/A
Command Injection - Generic 8 - body - Beta
Disabled
Disabled
This rule is merged into the original rule "Command Injection - Generic 8 - body" (ID: ).
This beta release includes the following changes and improvements:
Fixed an issue that could briefly block traffic to split tunnel excluded resources while the client was connecting or reconnecting.
Improved reauthentication reliability and fixed an issue where a reauthentication could force a new registration.
Improved client reaction to the current network lowering its MTU.
Added support for routing non-RFC 1918 local IPv4 networks through the WARP tunnel when unrestricted LAN inclusion is enabled by policy or MDM.
Improved DNS reliability on networks with lower MTUs by clamping the TCP maximum segment size (MSS) for DNS-over-HTTPS connections sent through the tunnel.
Improved API reliability by retrying requests dropped when reusing pooled connections.
The client no longer requires the Windows WLAN AutoConfig service to be running.
Implemented a service recovery mechanism backed by Windows scheduler task to start WARP service on system unlock if not already started.
Fixed slow captive portal checks causing the client service to become unresponsive or restart while connecting.
Fixed a race when switching tunnel protocols during key rotation that could prevent WireGuard from connecting.
Fixed the client continuing to report 'No network' after a successful manual disconnect.
Fixed Digital Experience Monitoring (DEX) HTTP tests failing TLS validation on Windows.
Fixed the client UI crashing at startup when it could not write to the Windows registry.
Fixed latency spikes and traffic interruptions during TPM-backed API authentication when hardware-backed registration is enabled.
Fixed trailing whitespace in BIOS serial numbers causing serial-number and client-certificate device posture checks to fail.
Fixed a client UI crash that could occur when the daemon connection was reset during an IPC request.
Fixed a startup crash when date formatting data for the system locale had not yet loaded.
This beta release includes the following changes and improvements:
Fixed an issue that could briefly block traffic to split tunnel excluded resources while the client was connecting or reconnecting.
Improved reauthentication reliability and fixed an issue where a reauthentication could force a new registration.
Improved client reaction to the current network lowering its MTU.
Added support for routing non-RFC 1918 local IPv4 networks through the WARP tunnel when unrestricted LAN inclusion is enabled by policy or MDM.
Improved DNS reliability on networks with lower MTUs by clamping the TCP maximum segment size (MSS) for DNS-over-HTTPS connections sent through the tunnel.
Improved API reliability by retrying requests dropped when reusing pooled connections.
Fixed Extra Logging failing to capture packets across all interfaces.
Fixed an issue that could prevent remote diagnostics from completing.
Fixed DNS connectivity checks failing on IPv6-only networks.
Fixed the client service exiting when its route-monitoring socket was closed after sleep or wake.
Fixed DNS enforcement checks making the client service unresponsive on systems with large routing tables.
Fixed slow captive portal checks causing the client service to become unresponsive or restart while connecting.
Fixed a race when switching tunnel protocols during key rotation that could prevent WireGuard from connecting.
Fixed the client continuing to report 'No network' after a successful manual disconnect.
Fixed a client UI crash that could occur when the daemon connection was reset during an IPC request.
Fixed a startup crash when date formatting data for the system locale had not yet loaded.
AI Gateway User Insights now gives you more context about the traffic flowing through your gateway. It shows what users and agents are doing with AI, and where a selected model may be more capable than a task requires.
On the analysis side, User Insights groups conversations by task, tracks conversation turns, and helps you compare model fit with cost and latency.
The Potential Savings view highlights requests that may work with faster or less expensive models without compromising output quality. These are the same signals that Cloudflare's Auto Router uses to select a model based on task and cost.
These new insights are available to all AI Gateway customers at no additional cost. For more information, refer to User Insights.
Browser Run sessions now accept multiple concurrent connections. Before, a session accepted only one connection at a time, and other Workers had to wait until that connection closed. Now multiple Workers can connect to the same browser at the same time.
Each puppeteer.connect() call opens its own Chrome DevTools Protocol (CDP) connection. Create a separate browser context for each request to keep its pages, cookies, and storage apart from other clients.
Containers custom instance types no longer limit disk based on memory. Previously, a custom instance type could have a maximum of 2 GB of disk for each 1 GiB of memory. You can now allocate up to the 20 GB disk maximum to any custom instance type.
Use this to run workloads that need more disk than memory, such as workloads with large container images, datasets, or build caches. The maximum image size is the same as the instance disk space, so more disk also lets you deploy larger images.
For example, a custom instance type with 1 vCPU and 3 GiB of memory was previously limited to 6 GB of disk. It can now use 20 GB:
The other custom instance type constraints do not change, including the minimum of 3 GiB of memory per vCPU. For the full list, refer to Custom Instance Types.
You can now tell a person on a laptop apart from a Mesh node or an AI agent running on Workers, without matching on connector email addresses or Mesh IP ranges — and see exactly which Cloudflare Tunnel and cloudflared replica received each session.
Mesh — Traffic sent from or delivered to a Cloudflare Mesh node. Previously, Mesh nodes were logged the same way as devices running the Cloudflare One Client, because Mesh nodes run the client in headless mode.
Workers VPC — Traffic sent by a Worker through a Workers VPC binding. Previously, Workers VPC sessions were not recorded in Network Session Logs.
Gateway network logs
To view these values in the dashboard, go to Zero Trust > Insights & Logs > Logs > Network logs, select Columns, and turn on Traffic Source and Traffic Destination. Both values also appear under Network query details when you open a log entry.
Network Session Logs
The zero_trust_network_sessions dataset, available through Logpush, includes the following fields:
Field
Description
OnrampType
How the session entered Cloudflare One. Values: CF1_CLIENT, MESH, WORKERS_VPC, MAGIC, OTHER.
Offramp
Where the session was routed. Sessions routed to a Mesh node report MESH.
SourceName
Name of the Worker that started the session. Only populated for Workers VPC sessions.
SourceID
Stable identifier of the Worker that started the session. Only populated for Workers VPC sessions.
DestinationReplicaID
The replica that served the session, such as a specific replica of a Mesh node or a cloudflared replica of a Cloudflare Tunnel.
For example, OnrampType = 'WORKERS_VPC' AND Offramp = 'MESH' returns every session where a Worker reached a service behind a Mesh node, and SourceName tells you which Worker it was.
See which tunnel and replica received a session
With DestinationReplicaID, you can now confirm which Cloudflare Tunnel and which cloudflared replica received traffic for a specific session. Combine it with the existing DestinationTunnelID field to trace a session to an exact tunnel replica — or Mesh node replica — when you run multiple replicas for high availability. The replica ID matches the Connector ID shown in the dashboard, so you can stream that replica's logs with cloudflared tail --connector-id.
Workers Cache now supports invalidate(), the soft counterpart of purge(). purge() deletes matching cached responses, so the next request is a cache miss. invalidate() keeps them but marks them stale, so the cache revalidates them with your Worker instead.
To revalidate a response, the cache sends your Worker a conditional request built from the validators stored with it — for example, If-None-Match carrying the cached ETag. If your Worker answers 304 Not Modified, the cache keeps the stored body. If your Worker answers with a full 200 response, that response replaces the cached one.
invalidate() accepts the same options as purge(): tags, pathPrefixes, or purgeEverything. It follows the same per-entrypoint scoping and resolves to the same result object. Call it as ctx.cache.invalidate(), or import cache from cloudflare:workers and call cache.invalidate().
Use invalidate() when one call covers many cached responses but only some of them changed. Your Worker needs to emit ETag or Last-Modified and answer matching conditional requests with 304. Each unchanged response then costs a validator check instead of a full regeneration:
src/index.jsjs
export default { async fetch(request, env, ctx) { if (request.method === "POST") { // Write the updated catalog, then mark every cached product page stale. await syncCatalog(env, await request.json()); await ctx.cache.invalidate({ tags: ["products"] }); return new Response("Synced"); } const product = await getProduct(env, request); const etag = `"${product.revision}"`; const headers = { "Cache-Control": "public, max-age=86400", "Cache-Tag": "products", ETag: etag, }; // The product has not changed since it was cached. Answer 304, and the // cache keeps the body it already has. if (request.headers.get("If-None-Match") === etag) { return new Response(null, { status: 304, headers }); } return new Response(renderProductPage(product), { headers }); },};
src/index.tsts
export default { async fetch(request, env, ctx): Promise<Response> { if (request.method === "POST") { // Write the updated catalog, then mark every cached product page stale. await syncCatalog(env, await request.json()); await ctx.cache.invalidate({ tags: ["products"] }); return new Response("Synced"); } const product = await getProduct(env, request); const etag = `"${product.revision}"`; const headers = { "Cache-Control": "public, max-age=86400", "Cache-Tag": "products", ETag: etag, }; // The product has not changed since it was cached. Answer 304, and the // cache keeps the body it already has. if (request.headers.get("If-None-Match") === etag) { return new Response(null, { status: 304, headers }); } return new Response(renderProductPage(product), { headers }); },} satisfies ExportedHandler<Env>;
You can now invalidate cached content instead of purging it. Invalidation marks matching content as stale. On the next request, Cloudflare revalidates the content with your origin. If your origin responds with 304 Not Modified, Cloudflare reuses the cached content instead of downloading it again.
Use invalidation to refresh a group of assets when only some of them have changed. For example, invalidate all content that shares a cache tag. Cloudflare reuses unchanged assets instead of downloading them again. This requires your origin to return an ETag or Last-Modified header and support conditional requests.
Invalidation supports the same selectors as purge: URLs, cache tags, hostnames, URL prefixes, and everything. To invalidate content, send a POST request to the new invalidate_cache endpoint:
In the dashboard, use Invalidate Cache on the Caching > Configuration page.
Your cache settings determine whether Cloudflare serves stale content while it revalidates. Cloudflare can also serve invalidated content stale if your origin returns a 5xx error or cannot be reached. To stop serving cached content, purge it instead.
Invalidation requests count toward the same rate limits as purge requests.
Purge behavior for Cache Reserve also changes with this release. For details, refer to Cache Reserve purge behavior.
Purge requests now force a cache miss for Cache Reserve content, regardless of purge type. Previously, purging by cache tag, hostname, prefix, or everything marked matching Cache Reserve content for revalidation. Purging by URL already removed content from Cache Reserve and is unchanged.
This change applies to purge requests from the API and the dashboard. Cache Reserve now handles purges the same way as the edge cache.
Cost impact
After a purge, the next request for affected content is a Cache Reserve miss. Your origin must deliver the content in full, even if it has not changed. Cloudflare then writes the content to Cache Reserve again, which is billed as a Class A operation.
Purging by tag, hostname, prefix, or everything does not delete content from Cache Reserve right away. Matching content continues to incur storage costs until a later request replaces it or its retention period ends.
If you frequently purge Cache Reserve content by tag, hostname, prefix, or everything, review the effect on your origin egress and Cache Reserve usage.
Keep revalidating Cache Reserve content
To keep content in Cache Reserve and revalidate it instead, send the same request to the new invalidate_cache endpoint:
In the dashboard, use Invalidate Cache on the Caching > Configuration page.
If your origin responds with 304 Not Modified, Cloudflare reuses the stored content instead of fetching it from your origin again. Compared with purging, invalidation reduces origin egress but not Cache Reserve operations. Updating the stored content after a 304 response is still a Class A operation. Invalidating by URL also updates the stored content when you send the request, which is a Class A operation.
Unlike the previous purge behavior, invalidation can serve stale content while it revalidates if your cache settings allow it. This applies only to copies in the edge cache, not to content served from Cache Reserve. Cloudflare can also serve invalidated content stale if your origin returns a 5xx error or cannot be reached. For details, refer to Invalidate cached content.
The Cloudflare CLI, cf, is now in beta. cf is one command-line interface for the public Cloudflare API and for Workers projects. Use it to manage zones, DNS, storage, and security settings, and to create, develop, and deploy Workers, without switching between tools.
Install cf globally, then sign in:
npm install --global cf
yarn global add cf
pnpm add --global cf
bun add --global cf
cf auth login
With cf, you can:
Manage resources across Cloudflare. More than 2,900 commands cover the public Cloudflare API, and most print their results as JSON.
Create and deploy Workers.cf init creates a project that uses cloudflare.config.ts, a typed configuration file. cf dev, cf build, and cf deploy develop, build, and deploy it.
Move from Wrangler.cf migrate converts a Wrangler configuration file to cloudflare.config.ts. You can also run cf resource commands in an existing Wrangler project without migrating it.
Work with coding agents.cf cli search finds the command for a task from a plain-language description, so an agent can find and run commands without prior knowledge of cf.
cf is in beta. Commands, configuration, and Build Output can change before the stable release.
A Worker can now call the Workflows it declares in the exports field of its Wrangler configuration through ctx.exports. You no longer need a workflows binding to call a Workflow from the Worker that defines it.
Each Workflow is keyed by class name, and has the same API as a Workflow binding:
A workflows binding and a workflow export with the same name share their instances. You can move a Workflow from a binding to an export without losing its instances.
wrangler dev, the Cloudflare Vite plugin, and the Workers Vitest integration run Workflows on ctx.exports locally. Local development requires Wrangler 4.142.0, @cloudflare/vite-plugin 1.61.0, or @cloudflare/vitest-plugin 1.3.0 or above.
In Vitest, introspectWorkflow() and introspectWorkflowInstance() still need a Workflow binding. To introspect a Workflow declared in exports, add a test-only binding to it.
Browser Run crawl jobs can publish lifecycle events to Cloudflare Queues. Subscribe to started, updated, and finished events to track progress or trigger downstream processing without polling.
To create an account-level subscription, run the following command:
account: The suppression applies to every sending domain and subdomain in your account. This is the default.
sending_domain: The suppression applies to one sending domain only. A suppression for mail.myappexample.com does not block mail from myappexample.com.
Most importantly, Email Sending now automatically creates bounce and complaint suppressions at the sending-domain level. This provides greater granularity by preventing an issue with one sending domain from suppressing the recipient across your entire account.
To add a suppression for one sending domain in the dashboard, go to Email Sending > Suppressions and select Sending domain in Scope. Imports can also set a scope for each row or a default scope.
In the API, pass scope when you create the suppression:
The suppressions API returns scope on every suppression. To list the suppressions for one domain, use scope_type=sending_domain&scope_value=mail.myappexample.com. If you omit scope, the API creates an account suppression, so existing integrations continue to work.
This update provides immediate defense against critical vulnerabilities affecting WordPress and JFrog Artifactory, including path traversal, local file inclusion (LFI), cross-site scripting (XSS), and authentication bypass exploits.
Key Findings
CVE-2026-87902: A high-severity Path Traversal and Local File Inclusion (LFI) vulnerability affecting WordPress. Unauthenticated attackers can exploit this flaw to read arbitrary files on the host server, potentially exposing sensitive configuration data or system files.
CVE-2026-42018 & CVE-2026-82329: Critical authentication bypass vulnerabilities affecting JFrog Artifactory. Successful exploitation allows unauthenticated attackers to bypass security controls and achieve unauthorized access to the Artifactory instance.
Impact
We strongly recommend that administrators apply the latest vendor patches for WordPress and JFrog Artifactory to fully secure origin servers.
Detailed Rule Changes
Ruleset
Rule ID
Legacy Rule ID
Description
Previous Action
New Action
Comments
Cloudflare Managed Ruleset
N/A
Wordpress - Path Traversal, Local File Inclusion - CVE:CVE-2026-87902
Custom spans in Workers now support more of the OpenTelemetry span API, so you can instrument more of your code and record errors directly on your spans.
tracing.startSpan(name) creates a span without making it the active span, and returns it. Other spans do not nest under it. Call span.end() when the operation is complete.
tracing.getActiveSpan() returns the currently active span. Use it to annotate the current span from helper functions and libraries without passing the span object through your code. Outside any custom span, it returns the invocation's root span.
span.recordException(exception) records an exception event on a span. It accepts an Error, a string, or an object with a code, name, or message.
span.setAttributes(attributes) sets multiple attributes at once. setAttribute() and setAttributes() now return the span, so you can chain calls.
Workers Metrics charts now show every release in the selected time range, including the full progression of gradual deployments. This makes it easier to correlate changes in memory, CPU time, errors, or latency with the code that was serving traffic.
A gradual deployment appears as a single rollout across the chart, with shading that increases as more traffic moves to the new version. Hover over a rollout to see the previous and new versions, the rollout duration, and the traffic percentage configured at each step.
Use these annotations to:
Find when a regression started — See which traffic percentage was configured when errors, latency, CPU time, or wall time changed.
Compare rollout stages — Check whether a metric changed as more traffic moved to the new version.
Confirm rollbacks — Rollbacks appear as separate release events, so you can check whether metrics recovered after a rollback.
Direct deployments that send 100% of traffic to a single version still appear as individual markers. Nearby direct deployments are grouped to reduce visual clutter. Versions that are only uploaded, or only configured at 0%, do not appear on metrics charts.
To view release annotations, open the Metrics tab for your Worker ↗︎.
1.1.1.1 now supports RFC 8509 ↗︎ root key trust anchor sentinels. They let you check whether the responding resolver trusts a DNSSEC root key ahead of a key rollover.
To check for KSK-2024 (key tag 38696), query DNSSEC-signed names in dnstest.dev:
# On a sentinel-aware resolver that trusts KSK-2024:# Returns NOERROR with an A answer.dig @1.1.1.1 root-key-sentinel-is-ta-38696.dnstest.dev. A +noall +comments +answer# Returns SERVFAIL without an answer.dig @1.1.1.1 root-key-sentinel-not-ta-38696.dnstest.dev. A +noall +comments +answer# CD bypasses sentinel processing and returns the original A answer.dig @1.1.1.1 root-key-sentinel-not-ta-38696.dnstest.dev. A +cdflag +noall +comments +answer
For background on DNSSEC validation, refer to DNSKEY.
MCP server portals are now generally available to all Cloudflare customers. A portal gives users one endpoint for approved Model Context Protocol (MCP) servers. Cloudflare Access logs tool, prompt, and resource activity.
Since the open beta, MCP server portals have added:
Gateway routing for HTTP logging and data loss prevention (DLP) scanning
Code Mode policies that control how portals reduce tool definitions and token use
Bandwidth throughput is split by object upload and download. The GraphQL Analytics API exposes the same bandwidth usage metrics that power the dashboard for your queries and analytics.
You can now declare the Workflows a Worker defines in the exports field of your Wrangler configuration file. Previously, a Worker could only define a Workflow through a workflows binding, even when the Worker never called the Workflow itself.
Key each entry by the name of the class that extends WorkflowEntrypoint:
A workflow export accepts the same settings as a workflows binding: limits, schedules, and default_retention. When you run wrangler deploy, Wrangler creates or updates the Workflow with these settings.
You can declare a Workflow as both a binding and an export. Both declarations must use the same class, and cannot set the same setting to different values.
A workflows binding to a Workflow in another Worker cannot use the same name as a Workflow export in this Worker. Workflow names are unique per account.
Workflow exports require Wrangler 4.139.0 or above.