{"record":{"id":"077248d03535ed3f","repo":"hashicorp/terraform","slug":"remote-workspace-terraform-version-q-does-not-mat","errorCode":null,"errorMessage":"Remote workspace Terraform version %q does not match local Terraform version %q","messagePattern":"Remote workspace Terraform version %q does not match local Terraform version %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote/backend.go","lineNumber":701,"sourceCode":"\t\t}\n\n\t\tworkspace, err = b.client.Workspaces.Create(context.Background(), b.organization, options)\n\t\tif err != nil {\n\t\t\treturn nil, diags.Append(fmt.Errorf(\"Error creating workspace %s: %v\", name, err))\n\t\t}\n\t}\n\n\t// This is a fallback error check. Most code paths should use other\n\t// mechanisms to check the version, then set the ignoreVersionConflict\n\t// field to true. This check is only in place to ensure that we don't\n\t// accidentally upgrade state with a new code path, and the version check\n\t// logic is coarser and simpler.\n\tif !b.ignoreVersionConflict {\n\t\twsv := workspace.TerraformVersion\n\t\t// Explicitly ignore the pseudo-version \"latest\" here, as it will cause\n\t\t// plan and apply to always fail.\n\t\tif wsv != tfversion.String() && wsv != \"latest\" {\n\t\t\treturn nil, diags.Append(fmt.Errorf(\"Remote workspace Terraform version %q does not match local Terraform version %q\", workspace.TerraformVersion, tfversion.String()))\n\t\t}\n\t}\n\n\tclient := &remoteClient{\n\t\tclient:       b.client,\n\t\torganization: b.organization,\n\t\tworkspace:    workspace,\n\n\t\t// This is optionally set during Terraform Enterprise runs.\n\t\trunID: os.Getenv(\"TFE_RUN_ID\"),\n\t}\n\n\treturn &remote.State{\n\t\tClient: client,\n\n\t\t// client.runID will be set if we're running in a HCP Terraform\n\t\t// or Terraform Enterprise remote execution environment, in which\n\t\t// case we'll disable intermediate snapshots to avoid extra storage","sourceCodeStart":683,"sourceCodeEnd":719,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote/backend.go#L683-L719","documentation":"Fallback Terraform-version conflict guard. When b.ignoreVersionConflict is false and the remote workspace's pinned TerraformVersion differs from the local CLI version (and is not the pseudo-version 'latest'), the backend refuses to proceed to avoid silently upgrading state with an incompatible version.","triggerScenarios":"workspace.TerraformVersion != tfversion.String() AND != \"latest\" AND b.ignoreVersionConflict == false. Happens right after workspace fetch in the state/client construction path.","commonSituations":"Local Terraform upgraded (e.g. 1.5 -> 1.6) but the TFC workspace is pinned to the older version; developer downgraded locally; CI image switched TF version while the workspace stayed pinned; workspace explicitly set to a fixed version in the UI.","solutions":["Align versions: set the workspace's Terraform Version in the TFC/TFE UI (Settings -> Version) to match your local CLI.","If intentional, bypass the guard with 'terraform init/plan/apply -ignore-remote-version' (sets b.ignoreVersionConflict=true).","Pin the local CLI to the workspace's version using tfenv / .terraform-version."],"exampleFix":"# before: workspace pinned to 1.5.7, local CLI is 1.6.0\n# option A - align workspace (in TFC UI: Settings > General > Terraform Version = 1.6.0)\n# option B - bypass locally\nterraform plan -ignore-remote-version","handlingStrategy":"validation","validationCode":"// Compare local vs workspace TF version before running, to fail with a clearer message.\nfunc versionsAligned(local, remote string) bool {\n    return remote == \"latest\" || remote == local\n}\n// or pass -ignore-remote-version when mismatch is intentional","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin the workspace TF version and the local CLI to the same version (tfenv/.terraform-version).","Add a CI check that compares `terraform version` against the workspace setting before plan/apply.","Document the -ignore-remote-version escape hatch and the state-corruption risk it carries."],"tags":["backend","remote-backend","version-conflict","workspace","state-safety","go"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}