hashicorp/terraform · error
error loading workspace
Error message
error loading workspace: %w
What it means
Thrown by the remote (Terraform Cloud / Enterprise) backend while constructing the operation context: it needs the workspace object to check ExecutionMode and decide whether to pull variables. b.fetchWorkspace wraps the TFC/TFE Workspaces.Read RPC and surfaces any non-success response here. The %w is the underlying tfe client / HTTP error.
Solutions
- Confirm the workspace name and organization in the backend config block match an existing TFC/TFE workspace (check exact casing).
- Verify the credential: re-run `terraform login <hostname>` or refresh TF_TOKEN_<hostname> / TFE_TOKEN; ensure the token belongs to the configured organization.
- Check network reachability to the TFC/TFE hostname (curl, TLS, proxy env vars HTTPS_PROXY / NO_PROXY).
- Consult status.hashicorp.com (or your TFE admin) for an active platform incident and retry.
Example fix
// before
workspaces { name = "prod-web" } // typo: real workspace is prod-webapp
// after
workspaces { name = "prod-webapp" } Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: verify workspace exists before running plan/apply
import tfe "github.com/hashicorp/go-tfe"
func workspaceExists(token, hostname, org, ws string) error {
cfg := &tfe.Config{Token: token, BaseURL: hostname}
c, err := tfe.NewClient(cfg)
if err != nil { return err }
_, err = c.Workspaces.Read(ctx, org, ws)
return err // nil == found
} Prevention
- Keep backend 'workspaces.name'/'prefix' and 'organization' in version control and CI-validated against the TFC org.
- Use a dedicated CI token and rotate it; fail fast on 401 instead of letting fetchWorkspace bubble up.
- Add a `terraform init` step in CI that exercises the backend config before plan.
When it happens
Trigger: b.fetchWorkspace(ctx, b.organization, op.Workspace) returns a non-nil error: the workspace name does not exist in the org, the organization is wrong, the API token is invalid/expired/scoped to another org, TFC/TFE returned 5xx, or the HTTP layer failed (DNS, TLS, proxy, timeout).
Common situations: Typo in workspaces.name/prefix in the backend block; organization renamed in TFC after backend config was written; terraform login token expired or revoked; self-hosted TFE hostname unreachable; corporate proxy blocking api.terraform.io; TFC incident.
Related errors
- error loading workspace
- error deleting workspace
- Error downloading state
- Error retrieving state
- failed checking for existing remote state
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/409683487110dfc6.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote/backend_context.go:108
if op.AllowUnsetVariables {
// If we're not going to use the variables in an operation we'll be
// more lax about them, stubbing out any unset ones as unknown.
// This gives us enough information to produce a consistent context,
// but not enough information to run a real operation (plan, apply, etc)
ret.PlanOpts.SetVariables = stubAllVariables(op.Variables, rootMod.Variables)
} else {
// The underlying API expects us to use the opaque workspace id to request
// variables, so we'll need to look that up using our organization name
// and workspace name.
remoteWorkspaceID, err := b.getRemoteWorkspaceID(context.Background(), op.Workspace)
if err != nil {
diags = diags.Append(fmt.Errorf("error finding remote workspace: %w", err))
return nil, nil, diags
}
w, err := b.fetchWorkspace(context.Background(), b.organization, op.Workspace)
if err != nil {
diags = diags.Append(fmt.Errorf("error loading workspace: %w", err))
return nil, nil, diags
}
if isLocalExecutionMode(w.ExecutionMode) {
log.Printf("[TRACE] skipping retrieving variables from workspace %s/%s (%s), workspace is in Local Execution mode", remoteWorkspaceName, b.organization, remoteWorkspaceID)
} else {
log.Printf("[TRACE] backend/remote: retrieving variables from workspace %s/%s (%s)", remoteWorkspaceName, b.organization, remoteWorkspaceID)
tfeVariables, err := b.client.Variables.ListAll(context.Background(), remoteWorkspaceID, nil)
if err != nil && err != tfe.ErrResourceNotFound {
diags = diags.Append(fmt.Errorf("error loading variables: %w", err))
return nil, nil, diags
}
if tfeVariables != nil {
if op.Variables == nil {
op.Variables = make(map[string]arguments.UnparsedVariableValue)
}
for _, v := range tfeVariables.Items {
if v.Category == tfe.CategoryTerraform {View on GitHub (pinned to d32a084675)