Get started Dashboard
Deployment safety ·
Part 10 of Platform playbooks

How to roll back a Cloudflare Workers deployment

Explore with AI

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.

On this page

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:

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:

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

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

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:

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.

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.
npx wrangler deploy --tag "$(git rev-parse --short HEAD)" --message "$PR_TITLE"
  1. 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.
  2. 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.
  3. 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.
  4. 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.

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 (8)

  1. Rollbacks · Cloudflare Workers docs
  2. Workers Wrangler commands · Cloudflare Workers docs
  3. Versions & deployments · Cloudflare Workers docs
  4. Gradual deployments · Cloudflare Workers docs
  5. Introducing Rollbacks for Workers Deployments · Cloudflare Blog
  6. Wrangler rollback command source · cloudflare/workers-sdk
  7. Wrangler dialogs source · cloudflare/workers-sdk
  8. Polylane full content

About the author

Boris Tane

Founder of Polylane

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

  1. 1 How to Monitor a Django App on Render
  2. 2 How to Monitor a FastAPI App on Railway: Logs, Traces and Alerts
  3. 3 How to Monitor a Supabase App in Production
  4. 4 How to Debug Cloudflare Workers Errors: Logs, Traces and Error Codes
  5. 5 How to debug Vercel function timeouts
  6. 6 Vercel 504 Gateway Timeout on Serverless Functions: Causes and Fixes
  7. 7 Cloudflare Workers error 1101: causes and how to fix it
  8. 8 Cloudflare Hyperdrive connection errors: causes and fixes
  9. 9 How to Monitor a Convex App in Production
  10. 10 How to roll back a Cloudflare Workers deployment
  11. 11 How to Monitor Vercel Cron Jobs: Heartbeats, Logs and Alerts
  12. 12 How to reduce Vercel Function cold starts
  13. 13 How to Monitor a Next.js App on Render
  14. 14 Modal container out of memory: find the cause and fix it
  15. 15 Fix Railway “Healthcheck failed!” on deploy

Related

Nobody should be on-call. Polylane watches your infra, finds what broke, and writes the fix.

Get started for free