How to Use Terraform State Push Command

Terraform state is Terraform's record of truth that maps your configuration to real infrastructure. If you change it incorrectly, the impact can be outsized. While `terraform state push` exists for edge cases like recovery and tightly controlled migrations, it can also overwrite backend state and cause Terraform to make the wrong decisions.

Mariusz Michalowski
Reviewed by: Tim DavisTim Davis

In this article, we’ll cover how terraform state push works, how to use it safely, and what the safer alternatives are.

What is the terraform state push command?

terraform state push uploads a local Terraform state file to the state storage configured for your current working directory, whether that is a remote backend or local state. It's a manual, last-resort command that is recommended to use only when you truly must intervene in state such as after a failed run or a carefully controlled manual repair.

The syntax is:

terraform state push [options] PATH
  • PATH is the file you want to push. If PATH is -, Terraform reads state data from standard input, validates it, and writes it to the configured backend.
  • -force tells Terraform to skip two safety checks: differing lineage and a higher remote serial. This can overwrite the destination state. Avoid it unless you're completely sure the state you're pushing is the correct one.
  • -ignore-remote-version is accepted only for configurations using the HCP Terraform CLI integration or the remote backend. It lets the operation proceed even if the local and remote Terraform versions do not match.

When you run terraform state push, Terraform tries to prevent unsafe overwrites. In particular, it checks:

  • State lineage: If lineage does not match, Terraform treats the states as unrelated and blocks the push.
  • Destination serial: If the remote serial is higher than the one you’re pushing, Terraform assumes the remote state is newer and blocks the push.

How to use terraform state push

Use terraform state push when you need to replace the current backend state with a local state file—typically after you’ve recovered state from a backup or (rarely) performed a controlled manual edit.

Start by confirming you’re operating on the right backend and workspace, then take a backup and push:

terraform init terraform workspace show terraform state pull > remote.tfstate.backup # Push a local state file to the configured backend terraform state push path/to/terraform.tfstate

Make sure the state file you plan to push is saved as UTF-8 without a BOM.
Note: Many Terraform state commands that modify state create a local backup file by default. You can control this behavior with the -backup option on those commands.

Example 1: Recover remote state after a failed apply created errored.tfstate

A common reason to use terraform state push is a run that partially completed and left you with an errored.tfstate file. After you resolve the underlying issue and you’re confident the errored snapshot is the one you want to become authoritative, you can push it to the backend:

terraform state push errored.tfstate

What makes this different from normal Terraform workflows is that you’re manually choosing which snapshot becomes authoritative. Terraform will still validate the file and perform its safety checks.

If the backend already has a higher serial, the push may be blocked to prevent you from replacing a newer snapshot with an older one.

If you reach for -force here, treat it like a destructive operation. It disables the lineage and serial protections and can overwrite the remote state.

Example 2: Migrate state to a new backend after switching from local to S3

A common use for terraform state push is moving an existing local terraform.tfstate into a newly configured remote backend, such as S3, after you reinitialize the working directory.

Use this pattern when you want to upload a specific local snapshot, instead of letting init migrate state automatically.

terraform init -reconfigure terraform state push terraform.tfstate

terraform init with -reconfigure prepares Terraform to use the new backend, then terraform state push uploads the local snapshot to that backend. Terraform may refuse the push if the remote state has a higher serial, because it assumes the remote is newer.

If you want Terraform to migrate state for you, run terraform init -migrate-state and skip terraform state push.

Why is terraform state push risky?

terraform state push is risky because it can overwrite your backend state directly. If you push the wrong (or stale) snapshot, you can corrupt the single source of truth Terraform uses for resource mapping. That can lead to plans that destroy, recreate, or “forget” real infrastructure because Terraform’s view of reality no longer matches what exists.

Common risks include:

  • Pushing an out-of-date state that discards newer changes from teammates or automation
  • Pushing a manually edited state that breaks resource addresses, dependencies, or provider metadata
  • Overwriting the wrong workspace or backend because you’re in the wrong directory or misconfigured for the target state

If your backend does not have strong versioning, or you don’t have an easy rollback path, recovery can be painful.

In most cases, you can avoid terraform state push by restoring state using backend versioning or by using purpose-built Terraform state commands that change state deterministically.

Common alternatives by intent:

  • Recover a bad state: Restore or roll back using your backend’s versioning (for example, S3 versioning, GCS object versioning, or Azure Blob snapshots)
  • Fix drift or missing resources: Use terraform plan -refresh-only to review changes, then terraform apply -refresh-only to update state to match real infrastructure
  • Bring an existing resource under Terraform management: Use terraform import, then run a normal terraform plan and terraform apply after updating configuration as needed
  • Rename or move addresses: Use terraform state mv (and terraform state rm only when you intentionally want Terraform to “forget” an object)
  • Provider or source changes: Use terraform state replace-provider for controlled migrations

Key points

In most situations, you can avoid terraform state push by using migration workflows and purpose-built state subcommands that change only what’s necessary. Treat a manual push as a last resort and only after you’ve backed up and validated what you’re about to make authoritative.

If you want tighter guardrails around Terraform workflows, use a purpose-built orchestration platform instead of relying on ad hoc scripts. Spacelift helps you run Terraform in a controlled workflow with policy as code, audit trails, and self-service patterns, so teams can move quickly without losing governance.

  • Policy as code (powered by Open Policy Agent)
  • Multi-IaC workflows
  • Self-service infrastructure
  • Integrations with third-party tools

If you want to learn more, create a free account or book a demo.

Note: HashiCorp changed Terraform’s license for newer releases, while earlier versions remain under their previous open-source license. OpenTofu is an open-source fork based on Terraform 1.5.6 and is a viable alternative for teams that want a community-governed option.

Terraform management made easy

Spacelift effectively manages Terraform state, more complex workflows, supports policy as code, programmatic configuration, context sharing, drift detection, resource visualization and includes many more features.

Learn more