{"record":{"id":"2c085187a3ac307d","repo":"hashicorp/terraform","slug":"migrating-state-from-hcp-terraform-or-terraform-en","errorCode":null,"errorMessage":"Migrating state from HCP Terraform or Terraform Enterprise to another backend is not \nyet implemented.\n\nPlease use the API to do this: https://developer.hashicorp.com/terraform/cloud-docs/api-docs/state-versions","messagePattern":"Migrating state from HCP Terraform or Terraform Enterprise to another backend is not \nyet implemented\\.\n\nPlease use the API to do this: https://developer\\.hashicorp\\.com/terraform/cloud-docs/api-docs/state-versions","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/meta_backend_migrate.go","lineNumber":594,"sourceCode":"\t_, sourceTFC := opts.Source.(*cloud.Cloud)\n\tcloudBackendDestination, destinationTFC := opts.Destination.(*cloud.Cloud)\n\n\tsourceWorkspaces, sourceSingleState, err := retrieveWorkspaces(opts.Source, opts.SourceType)\n\tif err != nil {\n\t\treturn err\n\t}\n\t//to be used below, not yet implamented\n\t// destinationWorkspaces, destinationSingleState\n\t_, _, err = retrieveWorkspaces(opts.Destination, opts.SourceType)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// from HCP Terraform to non-TFC backend\n\tif sourceTFC && !destinationTFC {\n\t\t// From HCP Terraform to another backend. This is not yet implemented, and\n\t\t// we recommend people to use the HCP Terraform API.\n\t\treturn errors.New(strings.TrimSpace(errTFCMigrateNotYetImplemented))\n\t}\n\n\t// Everything below, by the above two conditionals, now assumes that the\n\t// destination is always HCP Terraform.\n\tsourceSingle := sourceSingleState || (len(sourceWorkspaces) == 1)\n\tif sourceSingle {\n\t\tif cloudBackendDestination.WorkspaceMapping.Strategy() == cloud.WorkspaceNameStrategy {\n\t\t\t// If we know the name via WorkspaceNameStrategy, then set the\n\t\t\t// destinationWorkspace to the new Name and skip the user prompt. Here the\n\t\t\t// destinationWorkspace is not set to `default` thereby we will create it\n\t\t\t// in HCP Terraform if it does not exist.\n\t\t\topts.destinationWorkspace = cloudBackendDestination.WorkspaceMapping.Name\n\t\t}\n\n\t\tcurrentWorkspace, err := m.Workspace()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/command/meta_backend_migrate.go#L576-L612","documentation":"Returned by backendMigrateTFC (meta_backend_migrate.go:594) when the source backend is *cloud.Cloud (HCP Terraform / Terraform Enterprise) and the destination is a non-cloud backend. Terraform cannot migrate state OUT of HCP Terraform via the CLI; it returns errTFCMigrateNotYetImplemented pointing to the state-versions API. This is a hard limitation, not a config typo.","triggerScenarios":"Changing a backend block from `cloud {}` (or the legacy `remote {}`) to `backend \"s3\"` / `backend \"local\"` / etc. and running `terraform init` which triggers backendMigrateTFC.","commonSituations":"Team moving off HCP Terraform to a self-managed backend; consolidating from TFC to local for a sandbox; mistaken backend block edit.","solutions":["Use the HCP Terraform State Versions API (https://developer.hashicorp.com/terraform/cloud-docs/api-docs/state-versions) to download current state, then `terraform state push` it into the new backend.","Download the state JSON via the TFC UI 'Current state' / API, save as terraform.tfstate, configure the new backend, run `terraform init -reconfigure`, then `terraform state push terraform.tfstate`.","Confirm the source really must be cloud; if the migration direction is reversed (non-cloud -> cloud) it is supported and this error will not occur."],"exampleFix":"# before: cloud -> s3 triggers not-yet-implemented\n # (edit backend block cloud{} -> backend \"s3\" {})\n terraform init\n# after: export then push\n # 1. download state JSON from TFC API/UI -> tf.tfstate\n terraform init -reconfigure        # point at s3, discard old\n terraform state push tf.tfstate","handlingStrategy":"validation","validationCode":"// Detect the unsupported direction BEFORE running init.\n if sourceBackendIsCloud(cfg) && !destBackendIsCloud(newCfg) {\n     // export state via TFC API, then state push into the new backend\n     return errors.New(\"cloud->non-cloud migration unsupported; use API + terraform state push\")\n }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never expect `terraform init` to migrate OUT of HCP Terraform; plan an API export + `terraform state push` instead.","Verify migration direction is non-cloud -> cloud (supported) before editing the backend block."],"tags":["backend","hcp-terraform","state-migration","not-implemented","cloud"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}