# How to roll back a Cloudflare Workers deployment

> Roll back a Cloudflare Worker with wrangler rollback or the dashboard: find the right version ID, handle split deployments, and avoid data and binding traps.

Part 10 of [Platform playbooks](https://polylane.com/series/platform-playbooks/)
By Boris Tane, Founder of Polylane · Published October 18, 2026 · 11 min read
Canonical: https://polylane.com/learn/deployment-safety/how-to-roll-back-a-cloudflare-workers-deployment/

Run `npx wrangler rollback VERSION_ID --message "reason"`, or open Workers & Pages > your Worker > Deployments in the dashboard and choose Rollback on a known-good version. Cloudflare creates a new deployment with that version straight away, and it serves 100% of traffic on every route and domain. Your KV, R2, D1 and Durable Object data are not rolled back, and a rollback is blocked if a binding it needs was deleted or a Durable Object class changed since that version.

A Cloudflare Workers rollback takes one command. `wrangler rollback` with a version ID, or the **Rollback** action under **Deployments** in the dashboard, creates a new deployment that points at an older version. That deployment goes live on all your routes and domains at once. No rebuild runs and nothing new is uploaded: the old version is already stored, so you are only changing which one serves traffic.

To do it safely, you need three things: the ID of the last version that worked, confidence that your data still fits that version's code, and a fix in git so your next deploy doesn't bring the bad code back. This page covers each of them, then the cases where Cloudflare will refuse the rollback.

## What a Workers rollback does

In plain words, a Workers rollback is a new deployment that sends all traffic back to a version of your Worker that Cloudflare already holds. Workers tracks releases with two separate objects, and a rollback only touches one of them.

- A **version** is a full snapshot of your Worker: the bundled code, static assets, bindings and compatibility settings. Every version has a unique ID, a record of who created it, when and from where, and an optional message and tag. A new version appears every time you change code or configuration. `wrangler secret put` also creates a version, and it deploys that version straight away.
- A **deployment** decides which version or versions serve traffic. It points at one version taking 100% of traffic, or at two versions sharing traffic during a gradual deployment.

By default `wrangler deploy` does both jobs in one step: it creates a version and deploys it to 100% of traffic. A rollback makes a new deployment that points at a version you already have. Cloudflare's blog post from the launch says the rollback deployment gets its own ID but duplicates the deployment you rolled back to. Your deployment history keeps the full story: the bad deploy, then the rollback, with a message saying why.

What a version does **not** capture is the state of your storage. The docs say plainly that state changes in KV, R2, Durable Objects and D1 are not tracked with versions. When you roll back the code, the data stays exactly as the bad version left it. Most of the problems below come from this one fact.

## Rolling back with wrangler rollback, step by step

Use the terminal when you want an exact version ID, a recorded reason and a command you can paste into a runbook.

### 1. List recent deployments and versions

Run these from the project directory, or add `--name` to point at a different Worker:

```bash
npx wrangler deployments list
npx wrangler versions list
```

Wrangler shows the 100 most recent versions and deployments. Deployments are what decide which version serves traffic, so `deployments list` is the list you care about during an incident.

### 2. Confirm the version you want

Open the candidate and compare it with the current version:

```bash
npx wrangler versions view VERSION_ID
```

You are looking for the last version that served traffic cleanly. If the bad deploy also changed bindings, for example pointing at a new KV namespace or adding a queue, note it now. That difference decides whether the rollback is safe (see the section on data below).

### 3. Roll back to that version by ID

```bash
npx wrangler rollback VERSION_ID --message "Checkout 500s after deploy, rolling back"
```

The options are short:

- `VERSION_ID` is optional. Without it, Wrangler picks the version from the most recent earlier deployment that served 100% of traffic.
- `--name` runs the rollback on a named Worker, ignoring the name in your Wrangler config file.
- `--message` records the reason.
- `--yes` (or `-y`) accepts the defaults to prompts, so use it in CI and scripts.

Without `--message`, Wrangler first asks for an optional message (120 characters max), then asks you to confirm. In interactive mode you can choose from up to 100 recent versions.

### 4. Check that the old version is serving

```bash
npx wrangler deployments list
npx wrangler tail --version-id VERSION_ID --status error
```

The newest deployment should point at your target version and carry your message. `wrangler tail` accepts `--version-id` and `--status`, so you can watch live errors from the version you just restored and confirm they have stopped. Your local files don't change: the docs say a rollback has no effect on your local development environment.

### 5. Fix the code in git

Your repository and CI still hold the bad commit. Revert it or fix forward before the next merge, because the next `wrangler deploy` creates a new version from whatever is on the branch.

## Rolling back from the Cloudflare dashboard

The dashboard works well when you're on your phone, or when the person on call doesn't have Wrangler set up.

1. In the Cloudflare dashboard, open **Workers & Pages**.
2. Select your Worker, then **Deployments**.
3. On the version you want, select the three-dot menu on the right, then **Rollback**.
4. Enter a reason in the confirmation dialog and confirm.

The new deployment shows up at the top of the list with its own ID and your message.

## Rolling back a gradual deployment that splits traffic

If you release with `wrangler versions upload` and `wrangler versions deploy`, two versions may be sharing traffic when things go wrong. A rollback during a split replaces both versions with the one you pick, at 100% of traffic. The split ends immediately.

1. Work out which version in the split is healthy. Gradual deployments are built for this: filter by version with `wrangler tail --version-id`, or add the `ScriptVersion` field to a Workers Logpush job so every logged invocation carries the version ID, message and tag.
2. Roll back to the healthy version with `wrangler rollback VERSION_ID` or from the dashboard.
3. Check that the deployment now lists one version at 100%.

You can also move all traffic with `versions deploy`, which takes shorthand of the form `version-id@percentage`:

```bash
npx wrangler versions deploy GOOD_VERSION_ID@100% --message "Abort canary" --yes
```

Both paths end in the same place. Use `rollback` when you want the history to show the change as a rollback.

Durable Objects need extra care here. The docs say only one version of each Durable Object can run at a time, so a split deployment shares traffic between Durable Objects differently from stateless requests. Check the Durable Objects section of the gradual deployments docs before you rely on a split for them.

## When Cloudflare blocks the rollback, or the old code breaks on new data

Work through these checks before you click. The diagram shows the order.

```mermaid alt="Decision path for a Workers rollback: version age, binding and Durable Object changes, then data shape"
graph TB
A[Errors rise after a deploy] --> B{Two versions splitting traffic?}
B -->|yes| C[Pick the healthy version in the split]
B -->|no| D[Find the last good version ID]
C --> E{Within the last 100 versions?}
D --> E
E -->|no| F[Redeploy the old commit from git]
E -->|yes| G{Binding deleted or DO class changed?}
G -->|yes| F
G -->|no| H{Data shape changed since then?}
H -->|yes| I[Fix forward or make data readable]
H -->|no| J[Run wrangler rollback with the ID]
style I fill:#fee2e2,stroke:#fca5a5,color:#7f1d1d
style J fill:#d1fae5,stroke:#6ee7b7,color:#065f46
```

**100 most recently published versions are the only ones you can roll back to**

From Cloudflare's Workers rollbacks docs. Older versions need a fresh deploy from source.

### Only recent versions qualify

You can only roll back to the 100 most recently published versions. Every secret change and every `versions upload` counts as a version. A Worker that ships often, or a CI job that uploads a preview version on every push, can push a good release out of range sooner than you'd think. Past that limit, check out the old commit and run `wrangler deploy`.

### Deleted or changed resources stop the rollback

Cloudflare refuses the rollback when:

- a Durable Object class lifecycle change (through `exports` or the legacy `migrations` array) happened between the active version and the target, or
- the target version binds to an R2 bucket, KV namespace or queue that no longer exists.

More generally, the docs say you can't roll back if Developer Platform resources such as KV and D1 were deleted or modified between the two versions. A deploy that renamed a Durable Object class or swapped a KV namespace is a one-way door: plan to fix forward.

### Old code meets new data

This is the case Cloudflare can't detect for you. Resources connected to your Worker are not changed during a rollback, and the docs warn that errors can occur if the structure of your data changed between the two versions. Some examples:

- The bad version ran a D1 migration that renamed a column. The old code queries the old name and fails on every request.
- The bad version wrote KV values in a new JSON shape. The old code reads them and throws on a missing field.
- The bad version saved Durable Object storage in a format the old class can't parse.

If the bad deploy wrote data, decide before you roll back. Either the old code can read what was written, or you fix forward. If the old code throws, look for a spike of uncaught exceptions straight after the rollback.

## Rollback mistakes that turn one incident into two

**Running `wrangler rollback` with no ID.** Without an ID, Wrangler targets the version from the most recent earlier deployment that served 100% of traffic. That is not always the release you have in mind: `wrangler secret put` creates and deploys a version, so a secret change can make the previous deployment one you don't expect. Fix: always pass the ID you checked in `deployments list`.

**Letting CI redeploy the bad commit.** A rollback changes nothing in git. The next merge to main runs `wrangler deploy`, or Workers Builds builds the branch, and the broken code goes live again. Fix: revert the commit right after the rollback, or pause the pipeline until the fix lands.

**Rolling back from a script without recording why.** In a non-interactive context, Wrangler's prompts fall back to their defaults, so the rollback goes ahead with the default message `Rollback`. Weeks later, nobody can tell from the history what went wrong. Fix: pass `--message` with the real reason, plus `--yes`.

**Rolling back the wrong Worker.** Wrangler reads the Worker name from the config file in the current directory. In a monorepo, or with one config per environment, that may not be the Worker that is failing. Fix: pass `--name` explicitly and check the name in the output.

**Treating a dashboard variable edit as safe.** Wrangler overrides environment variables changed in the dashboard on the next deploy unless you set `--keep-vars`. A rollback restores the variables stored in the older version, so a hotfix made in the dashboard can disappear too. Fix: keep config in your Wrangler file and treat it as the source of truth.

**Rolling back across a data migration.** See the section above. Fix: check whether the bad version wrote anything before you choose rollback over fixing forward.

## Making the next rollback a one-minute job

A rollback is fast. Finding the right version ID during an incident is the slow part. Set these up now:

1. **Label every version.** `wrangler deploy` and `wrangler versions upload` accept `--message` and `--tag`. Put the git commit SHA in the tag and the PR title in the message, and `deployments list` becomes readable at 3am.

```bash
npx wrangler deploy --tag "$(git rev-parse --short HEAD)" --message "$PR_TITLE"
```

2. **Put the version on every log line.** Add `ScriptVersion` to your Logpush job, or read the version ID in code through the version metadata binding and attach it to your logs. I built and led the Workers observability team at Cloudflare, and the version ID is the first field I'd want on every event: without it, you can't tell whether the errors started with the deploy.
3. **Release through a split.** Upload with `wrangler versions upload`, send a small share of traffic to the new version with `wrangler versions deploy`, and compare errors by version before moving to 100%. If the new version is bad, rolling back only touches the share of traffic it was serving.
4. **Keep a rollback runbook.** Write down the exact `wrangler rollback VERSION_ID --name WORKER --message` line, who has an API token that can run it, and the check that comes after it.
5. **Flag binding and migration changes in review.** A pull request that deletes a KV namespace, renames a Durable Object class or changes a D1 schema removes your rollback option. Reviewers should know that before it merges.

## Spotting the deploy that needs rolling back with Polylane

Polylane detects production issues and fixes them by opening pull requests. It connects to Cloudflare, so when a Worker regresses after a deploy, it works out why, and the fix arrives ready for your team's normal review.

Running on Cloudflare? See [how Polylane monitors Cloudflare in production](https://polylane.com/for/cloudflare/).

## Common questions

**Does wrangler rollback roll back my D1, KV or R2 data?**

No. Cloudflare's docs say state changes in KV, R2, Durable Objects and D1 are not tracked with versions, and connected resources don't change during a rollback. If the bad version changed your data's shape, the old code may fail when it reads that data, so fix forward or make the data readable first.

**How far back can I roll back a Cloudflare Worker?**

To the 100 most recently published versions. Every deploy, `versions upload` and `wrangler secret put` creates a version, so busy Workers reach that limit quickly. For anything older, check out the old commit and run `wrangler deploy`.

**What does wrangler rollback do without a version ID?**

It rolls back to the version from the most recent earlier deployment that served 100% of traffic. A secret change creates and deploys a version, so that may not be the release you expect. Pass the ID you confirmed in `wrangler deployments list`.

**How do I run a Workers rollback in CI without prompts?**

Pass `--yes` (or `-y`), which accepts the defaults to prompts, and `--message` with the reason, for example `npx wrangler rollback VERSION_ID --name my-worker --message "auto rollback" --yes`. Without a message, a non-interactive run records the default message `Rollback`.

**Why does Cloudflare refuse to roll back my Worker?**

Usually a Durable Object class lifecycle change (through `exports` or `migrations`) happened since the target version, or the target binds to an R2 bucket, KV namespace or queue that no longer exists. Either way the rollback is blocked, and you have to deploy a fixed version.

**What happens if I roll back during a gradual deployment?**

The split ends. Both versions are replaced by the one you pick, and it serves 100% of traffic. Pick the healthy version from the split, then roll back to it with Wrangler or the dashboard.

**Will my next push redeploy the broken code?**

Yes, unless you change git. A rollback only changes which stored version serves traffic, and your local files and repository stay as they were. Revert or fix the commit before CI or Workers Builds deploys the branch again.

## Sources

- [Rollbacks · Cloudflare Workers docs](https://developers.cloudflare.com/workers/versions-and-deployments/rollbacks/)
- [Workers Wrangler commands · Cloudflare Workers docs](https://developers.cloudflare.com/workers/wrangler/commands/workers/)
- [Versions & deployments · Cloudflare Workers docs](https://developers.cloudflare.com/workers/versions-and-deployments/)
- [Gradual deployments · Cloudflare Workers docs](https://developers.cloudflare.com/workers/versions-and-deployments/gradual-deployments/)
- [Introducing Rollbacks for Workers Deployments · Cloudflare Blog](https://blog.cloudflare.com/introducing-rollbacks-for-workers-deployments/)
- [Wrangler rollback command source · cloudflare/workers-sdk](https://raw.githubusercontent.com/cloudflare/workers-sdk/main/packages/wrangler/src/versions/rollback/index.ts)
- [Wrangler dialogs source · cloudflare/workers-sdk](https://raw.githubusercontent.com/cloudflare/workers-sdk/main/packages/wrangler/src/dialogs.ts)
- [Polylane full content](https://polylane.com/llms-full.txt)

## About the author

Boris Tane is the founder of Polylane. He previously founded Baselime, observability for the future of the cloud, which Cloudflare acquired. At Cloudflare he built and led the Workers observability team.

## More in this series

[Platform playbooks](https://polylane.com/series/platform-playbooks/)

1. [How to Monitor a Django App on Render](https://polylane.com/learn/monitoring-coverage/how-to-monitor-a-django-app-on-render/)
2. [How to Monitor a FastAPI App on Railway: Logs, Traces and Alerts](https://polylane.com/learn/monitoring-coverage/how-to-monitor-a-fastapi-app-on-railway/)
3. [How to Monitor a Supabase App in Production](https://polylane.com/learn/monitoring-coverage/how-to-monitor-a-supabase-app-in-production/)
4. [How to Debug Cloudflare Workers Errors: Logs, Traces and Error Codes](https://polylane.com/learn/troubleshooting/how-to-debug-cloudflare-workers-errors/)
5. [How to debug Vercel function timeouts](https://polylane.com/learn/troubleshooting/how-to-debug-vercel-function-timeouts/)
6. [Vercel 504 Gateway Timeout on Serverless Functions: Causes and Fixes](https://polylane.com/learn/troubleshooting/vercel-504-gateway-timeout-on-serverless-functions/)
7. [Cloudflare Workers error 1101: causes and how to fix it](https://polylane.com/learn/troubleshooting/cloudflare-workers-error-1101/)
8. [Cloudflare Hyperdrive connection errors: causes and fixes](https://polylane.com/learn/troubleshooting/cloudflare-hyperdrive-connection-errors/)
9. [How to Monitor a Convex App in Production](https://polylane.com/learn/monitoring-coverage/how-to-monitor-a-convex-app-in-production/)
10. [How to roll back a Cloudflare Workers deployment](https://polylane.com/learn/deployment-safety/how-to-roll-back-a-cloudflare-workers-deployment/)
11. [How to Monitor Vercel Cron Jobs: Heartbeats, Logs and Alerts](https://polylane.com/learn/monitoring-coverage/how-to-monitor-vercel-cron-jobs/)
12. [How to reduce Vercel Function cold starts](https://polylane.com/learn/troubleshooting/how-to-reduce-vercel-function-cold-starts/)
13. [How to Monitor a Next.js App on Render](https://polylane.com/learn/monitoring-coverage/how-to-monitor-a-next-js-app-on-render/)
14. [Modal container out of memory: find the cause and fix it](https://polylane.com/learn/troubleshooting/modal-container-out-of-memory/)
15. [Fix Railway “Healthcheck failed!” on deploy](https://polylane.com/learn/troubleshooting/railway-healthcheck-failed/)

Previous: [How to Monitor a Convex App in Production](https://polylane.com/learn/monitoring-coverage/how-to-monitor-a-convex-app-in-production/)
Next: [How to Monitor Vercel Cron Jobs: Heartbeats, Logs and Alerts](https://polylane.com/learn/monitoring-coverage/how-to-monitor-vercel-cron-jobs/)

## Related

- [How to correlate incidents with deploys using evidence](https://polylane.com/learn/deployment-safety/how-to-correlate-incidents-with-deploys/): Learn how to correlate incidents with deploys using release markers, metrics, logs and verified GitHub, Vercel, Cloudflare and Kubernetes change events.
- [What is change intelligence? A production safety guide](https://polylane.com/learn/deployment-safety/what-is-change-intelligence/): What is change intelligence? Learn how deploys, config, flags, infrastructure and dependency changes connect to incidents, using tools you already have.
- [Fix “Durable Object reset because its code was updated”](https://polylane.com/learn/troubleshooting/cloudflare-durable-object-reset-because-its-code-was-updated/): Why a deploy makes Cloudflare Durable Objects throw “reset because its code was updated”, and how to retry safely, keep clients connected and lose no state.

Get started with one command: `curl -fsSL https://polylane.com/setup | bash` installs the CLI, connects your coding agents, and creates the account.
