hashicorp/terraform · error

error starting operation

Error message

error starting operation: %s

What it means

Returned by `Meta.RunOperation` when the backend's `Operation(ctx, opReq)` factory itself fails before any operation can run. This is distinct from an operation that starts but later fails (those surface via the `RunningOperation.Result` channel). The backend implementation refused to create the operation machinery — typically a configuration or precondition problem inside the backend.

Solutions

  1. Run `terraform init` to re-initialize the backend and validate its configuration.
  2. Inspect the wrapped `%s` detail — it usually names the specific backend precondition that failed.
  3. For cloud backends, confirm `workspaces.{name,tags,project}` in the `cloud` block matches existing HCP Terraform workspaces.
  4. Clear a stale lock only if you are certain no other run is active: `terraform force-unlock <lock-id>`.
  5. Re-authenticate if the backend credential has expired (`terraform login`).

Example fix

// before: backend misconfiguration
backend "remote" { organization = "acme" workspaces { name = "" } }
// after
cloud { organization = "acme" workspaces { name = "prod" } }
# then
terraform init
terraform apply
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

// Wrap RunOperation; distinguish start-failure from operation-result failure.
op, err := m.RunOperation(b, opReq)
if err != nil {
    // operation never started — backend/config issue, fix via init
    return err
}
result := <-op.Result
if result.State == nil { /* operation ran but failed separately */ }

Prevention

When it happens

Trigger: `b.Operation` returns `(nil, err)` because the backend cannot initialize an operation runner — e.g. a local backend with an invalid state lock, a remote/cloud backend whose configuration is incomplete, or a backend that requires a workspace that is not selected. `RunOperation` wraps the error and returns immediately.

Common situations: Cloud/remote backend `workspaces.name` or `workspaces.tags` misconfiguration; backend init was skipped (`terraform init` not run after a backend change); a stale or corrupted local state lock file; concurrent `terraform apply` on the same workspace holding a lock; backend credentials expired between init and the operation.

Related errors


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

Appendix: source

Thrown at internal/command/meta.go:503

// until that operation completes or is interrupted, and then returns
// the RunningOperation object representing the completed or
// aborted operation that is, despite the name, no longer running.
//
// An error is returned if the operation either fails to start or is cancelled.
// If the operation runs to completion then no error is returned even if the
// operation itself is unsuccessful. Use the "Result" field of the
// returned operation object to recognize operation-level failure.
func (m *Meta) RunOperation(b backendrun.OperationsBackend, opReq *backendrun.Operation) (*backendrun.RunningOperation, error) {
	if opReq.View == nil {
		panic("RunOperation called with nil View")
	}
	if opReq.ConfigDir != "" {
		opReq.ConfigDir = m.normalizePath(opReq.ConfigDir)
	}

	op, err := b.Operation(m.CommandContext(), opReq)
	if err != nil {
		return nil, fmt.Errorf("error starting operation: %s", err)
	}

	// Wait for the operation to complete or an interrupt to occur
	select {
	case <-m.ShutdownCh:
		// gracefully stop the operation
		op.Stop()

		// Notify the user
		opReq.View.Interrupted()

		// Still get the result, since there is still one
		select {
		case <-m.ShutdownCh:
			opReq.View.FatalInterrupt()

			// cancel the operation completely
			op.Cancel()

View on GitHub (pinned to d32a084675)