Durable Object class exports·续2
The following table lists the allowed and forbidden fields for each state:
state |
Required | Forbidden |
|---|---|---|
"created" (default) |
storage |
renamed_to, transferred_to, transfer_from |
"deleted" |
(none) | storage, renamed_to, transferred_to, transfer_from |
"renamed" |
renamed_to |
storage, transferred_to, transfer_from |
"transferred" |
transferred_to |
storage, renamed_to, transfer_from |
"expecting-transfer" |
storage, transfer_from |
renamed_to, transferred_to |
Error reference
When a deploy fails reconciliation, Cloudflare returns one error per class along with a structured scenario tag, a human-readable message, and where applicable a suggestion and referencing_scripts list:
| Scenario | Meaning | How to fix |
|---|---|---|
provisioned_class_missing_from_config |
A namespace exists for a class that the Worker code still exports, but exports has no entry for it. |
Add a live entry (state: "created") to keep the namespace, or add a tombstone (deleted, renamed, or transferred) to retire it. |
config_export_not_in_code |
A live entry declares a class that the Worker code does not export. | Add the class to your code, or replace the entry with a tombstone. |
config_references_nonexistent_class |
A live entry declares a class that is neither in code nor provisioned. | Remove the entry, or add the class to your Worker code. |
orphaned_provisioned_namespace |
A namespace exists for a class that is neither in code nor declared. | Add a tombstone for the class, or add the class back to code and exports. |
invalid_export |
An exports entry is structurally invalid — for example, requesting legacy-kv for a new namespace, or a class that maps to more than one provisioned namespace. |
Correct the entry: use "storage": "sqlite" for new namespaces, or resolve the duplicate with a deleted or renamed tombstone. |
tombstone_delete_class_still_in_code |
A deleted tombstone names a class that is still exported in code. |
Remove the class from your code first, then deploy the tombstone. |
tombstone_delete_blocked_by_external_bindings |
Another Worker in the account binds to the namespace being deleted. | Redeploy the referencing Workers without the binding, then re-run your deploy. |
tombstone_renamed_to_occupied |
A renamed_to target collides with an existing namespace under that name. |
Delete the colliding namespace via its own deleted tombstone in a prior deploy. |
transferred_pending_not_found |
A transferred tombstone has no matching expecting-transfer entry on the target. |
Deploy the target Worker first with an expecting-transfer entry naming this Worker. |
transferred_target_missing |
The target Worker named by transferred_to no longer exists. |
Update transferred_to to a valid target, or remove the tombstone. |
transferred_target_mismatch |
The transferred_to value does not match the target recorded by the pending transfer. |
Set transferred_to to the pending transfer's target, or have the target cancel its expecting-transfer entry before redirecting. |
transferred_source_in_dispatch_namespace |
The source Worker declaring the transferred tombstone is in a dispatch namespace; cross-dispatch transfer is not supported. |
Perform the transfer within a single dispatch-namespace context. |
transferred_target_in_dispatch_namespace |
The target of a transferred tombstone is in a dispatch namespace; cross-dispatch transfer is not supported. |
Cancel the pending transfer by having the target redeploy without expecting-transfer, or keep both Workers in the same context. |
phase_one_transfer_after_commit_mismatch |
The target's namespace was transferred from a different source than the one declared. | Remove the expecting-transfer entry — the transfer cannot be redirected after commit. |
phase_one_transfer_target_class_provisioned |
The target Worker already owns a namespace for the class. | Replace the expecting-transfer entry with a normal live entry, or delete the existing namespace first. |
phase_one_transfer_duplicate |
Another expecting-transfer hint is already in flight for the same class. |
Cancel the existing pending transfer first by removing or replacing its entry. |
phase_one_transfer_source_missing |
The source Worker named by transfer_from does not exist in the account. |
Correct the source Worker name. |
phase_one_transfer_source_namespace_missing |
The source Worker has no namespace for the class. | Make sure the source Worker has the class deployed before the target declares expecting-transfer. |
phase_one_transfer_source_in_dispatch_namespace |
The source Worker is in a dispatch namespace; cross-dispatch transfer is not supported. | Move the transfer within a single dispatch-namespace context. |
phase_one_transfer_target_in_dispatch_namespace |
The target Worker is in a dispatch namespace; cross-dispatch transfer is not supported. | Move the transfer within a single dispatch-namespace context. |
storage_type_mismatch |
The declared storage value does not match the provisioned namespace's storage backend. |
Storage backends cannot be changed in place. Delete the namespace and re-provision it under the new backend if you genuinely need to switch. |
free_tier_requires_sqlite |
The account's plan only supports SQLite-backed namespaces, but the entry requests legacy-kv. |
Use "storage": "sqlite". |
Note
The blocking error tombstone_delete_class_still_in_code (specific to deleted tombstones) is distinct from the non-blocking tombstone_class_still_in_code info notice emitted for renamed and transferred tombstones. The latter is the expected zero-downtime rollout pattern — refer to Reading the reconciliation output.
Constraints and limitations
- Durable Object entries in
exportsare mutually exclusive withmigrations. A Worker configuration that contains both is rejected at validation. Workflow entries inexportscan be used alongsidemigrations. Once a Worker has been deployed withexports, subsequent deploys must continue to useexports(or neither, which reconciles against an empty config and is usually a mistake). wrangler versions uploaddoes not apply lifecycle changes. Just like the legacymigrationsarray, Durable Object lifecycle changes can only be applied viawrangler deploy. If your Wrangler configuration containsexportsentries,wrangler versions uploadfails fast with an actionable error. Refer to Deployment management - Durable Object migrations.- Gradual deployments are not supported with
exports. Lifecycle changes are atomic at the Cloudflare control plane and cannot be rolled out gradually. Refer to Gradual deployments with Durable Objects - Durable Object class lifecycle changes. - Rollbacks cannot cross a lifecycle change. You cannot roll back to a version deployed before an
exports-driven lifecycle change. Refer to Rollbacks - Bindings. - Storage backends are immutable once provisioned. You cannot change a namespace's
storagevalue in place; delete and re-provision instead.
Migrate from the legacy migrations flow
Existing Workers using the migrations array can move to exports without any data migration. The provisioned namespaces remain in place; only the configuration shape changes.
To determine a class's existing storage backend, trace it to the migration that originally created it. Classes introduced through new_sqlite_classes use sqlite, while classes introduced through new_classes use legacy-kv.
- Identify the live Durable Object classes your Worker exports today. Each class with an active namespace becomes a live
exportsentry. - Replace the
migrationsarray with anexportsmap. For each existing class, add an entry keyed by the class name with"type": "durable-object". Match the existing storage backend with"storage": "sqlite"or"storage": "legacy-kv". - Remove the
migrationsarray from your configuration. - Deploy.
Side-by-side, the equivalent of a typical migrations history is:
{
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["ChatRoom"] }
]
}
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "ChatRoom" ]
{
"exports": {
"ChatRoom": { "type": "durable-object", "storage": "sqlite" }
}
}
[exports.ChatRoom]
type = "durable-object"
storage = "sqlite"
Future lifecycle changes (deletes, renames, transfers) happen entirely through exports — there is no equivalent of the tag field and no need to keep historical entries. The current state of your exports map is the source of truth.
Caution
Once a Worker has been deployed with exports, subsequent deploys cannot return to the legacy migrations array. Plan your transition accordingly.
Was this helpful?
YesNo
On this page
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/#page","headline":"Durable Object class exports","description":"Use the declarative exports field in wrangler.json to manage Durable Object class lifecycle — create, delete, rename, and transfer Durable Object classes.","url":"https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/","inLanguage":"en","image":"https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/og.png?v=0b5647d0df272fdf","dateModified":"2026-09-28","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
description: Configure Durable Object bindings across Wrangler environments for staging, production, and custom deployments. title: Environments image: https://developers.cloudflare.com/durable-objects/reference/environments/og.png?v=dc5ab0423d9f8388
Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/durable-objects/llms.txt
Use this file to discover all available pages before exploring further.
Docs