hashicorp/terraform · error

Remote workspace Terraform version

Error message

Remote workspace Terraform version %q does not match local Terraform version %q

What it means

Fallback version-guard: after selecting/creating the workspace, the backend compares workspace.TerraformVersion (remoteTFVersion) against the running local Terraform binary (tfversion.String()), unless ignoreVersionConflict was set by an upstream code path. 'latest' is explicitly allowed because it would always mismatch. A mismatch aborts before state operations to prevent silent state upgrades.

Solutions

  1. Update the workspace's Terraform version in TFE/HCP to match the local binary.
  2. Downgrade or upgrade the local Terraform/OpenTofu binary to match the workspace.
  3. Set the workspace version to "latest" if your workflow tolerates floating.
  4. If you genuinely want to proceed despite mismatch, follow the documented migration path that sets ignoreVersionConflict rather than working around the guard.

Example fix

# before: local 1.7.5, workspace pinned to 1.6.6
terraform {
  required_version = "~> 1.7"
  cloud { workspaces { name = "prod" } }
}
# Workspace settings -> Terraform Version -> set to 1.7.5
Defensive patterns

Strategy: validation

Validate before calling

// ensure versions agree before running
func versionsAgree(localTFV, remoteTFV string) error {
    if remoteTFV == "latest" { return nil }
    if localTFV != remoteTFV {
        return fmt.Errorf("local %s != workspace %s; pin workspace or upgrade local", localTFV, remoteTFV)
    }
    return nil
}

Prevention

When it happens

Trigger: Workspace's configured TerraformVersion != local binary version AND != "latest", with b.ignoreVersionConflict == false. Happens when an operator pinned the workspace to e.g. 1.6.x but the CI runner has 1.7.x, or vice versa; or after a local upgrade with no matching workspace update.

Common situations: Developer upgraded their local Terraform/OpenTofu and forgot to bump the workspace version; CI image pinned to a different minor than the workspace; downstream of an admin changing the workspace's pinned version.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/79d76f703be7183f. Report an issue: GitHub.

Appendix: source

Thrown at internal/cloud/backend.go:874

			}
			_, err = b.client.Workspaces.AddTagBindings(context.Background(), workspace.ID, options)
		}

		if err != nil {
			return nil, diags.Append(fmt.Errorf("error updating workspace %q tags: %w", name, err))
		}
	}

	// This is a fallback error check. Most code paths should use other
	// mechanisms to check the version, then set the ignoreVersionConflict
	// field to true. This check is only in place to ensure that we don't
	// accidentally upgrade state with a new code path, and the version check
	// logic is coarser and simpler.
	if !b.ignoreVersionConflict {
		// Explicitly ignore the pseudo-version "latest" here, as it will cause
		// plan and apply to always fail.
		if remoteTFVersion != tfversion.String() && remoteTFVersion != "latest" {
			return nil, diags.Append(fmt.Errorf("Remote workspace Terraform version %q does not match local Terraform version %q", remoteTFVersion, tfversion.String()))
		}
	}

	return &State{tfeClient: b.client, organization: b.Organization, workspace: workspace, enableIntermediateSnapshots: false}, diags
}

// Operation implements backendrun.OperationsBackend.
func (b *Cloud) Operation(ctx context.Context, op *backendrun.Operation) (*backendrun.RunningOperation, error) {
	// Retrieve the workspace for this operation.
	w, err := b.fetchWorkspace(ctx, b.Organization, op.Workspace)
	if err != nil {
		return nil, err
	}

	// Terraform remote version conflicts are not a concern for operations. We
	// are in one of three states:
	//
	// - Running remotely, in which case the local version is irrelevant;

View on GitHub (pinned to d32a084675)