hashicorp/terraform · error

error uploading state

Error message

error uploading state: %v

What it means

Primary state-upload path: StateVersions.Upload streams the raw state plus metadata to TFC/TFE. ErrStateVersionUploadNotSupported is handled separately (compatibility fallback); every other failure is flagged via r.stateUploadErr=true (which suppresses auto-unlock) and returned here.

Solutions

  1. If the error is a serial/lineage conflict, re-pull state and re-plan rather than forcing.
  2. Use -force (force-push) only if you intentionally want to overwrite history.
  3. Ensure no other run/user is concurrently writing to the workspace.
  4. Confirm the token has 'Write State' permission and the upload size is under the TFC limit.
  5. On transient 5xx/network errors, re-run; stateUploadErr will require an explicit unlock.
Defensive patterns

Strategy: validation

Validate before calling

// Reject serial regressions client-side before upload
if cur != nil && !force && uploadSerial <= cur.Serial {
    return fmt.Errorf("refusing to push serial %d over current %d (use force)", uploadSerial, cur.Serial)
}

Try / catch

// Retry only transient 5xx/network, not serial/lock conflicts
if errors.Is(err, tfe.ErrStateVersionUploadNotSupported) { /* fallback */ }
if isTransient(err) { backoff.Retry(upload, ...) } else { flagUnlockRequired(err) }

Prevention

When it happens

Trigger: StateVersions.Upload returns an error other than ErrStateVersionUploadNotSupported: serial conflict (current state serial >= upload serial without force), workspace locked by another run, 401/403, state-too-large, 5xx, or network failure during streaming.

Common situations: Two concurrent applies racing on the same workspace; `terraform apply` after a state push that bumped the serial; token lacks write permission; very large state hitting the upload ceiling; TFC storage backend degraded.

Related errors


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

Appendix: source

Thrown at internal/backend/remote/backend_state.go:156

	}

	// If we have a run ID, make sure to add it to the options
	// so the state will be properly associated with the run.
	if r.runID != "" {
		options.Run = &tfe.Run{ID: r.runID}
	}

	// Create the new state.
	// Create the new state.
	_, err = r.client.StateVersions.Upload(ctx, r.workspace.ID, options)
	if errors.Is(err, tfe.ErrStateVersionUploadNotSupported) {
		// Create the new state with content included in the request (Terraform Enterprise v202306-1 and below)
		log.Println("[INFO] Detected that state version upload is not supported. Retrying using compatibility state upload.")
		return diags.Append(r.uploadStateFallback(ctx, stateFile, state, o))
	}
	if err != nil {
		r.stateUploadErr = true
		return diags.Append(fmt.Errorf("error uploading state: %v", err))
	}

	return nil
}

// Delete the remote state.
func (r *remoteClient) Delete() tfdiags.Diagnostics {
	var diags tfdiags.Diagnostics
	err := r.client.Workspaces.Delete(context.Background(), r.organization, r.workspace.Name)
	if err != nil && err != tfe.ErrResourceNotFound {
		return diags.Append(fmt.Errorf("error deleting workspace %s: %v", r.workspace.Name, err))
	}

	return nil
}

// EnableForcePush to allow the remote client to overwrite state
// by implementing remote.ClientForcePusher

View on GitHub (pinned to d32a084675)