hashicorp/terraform · error

error loading variables

Error message

error loading variables: %w

What it means

Thrown by Cloud.FetchVariables when b.client.Variables.ListAll(ctx, remoteWorkspaceID, nil) fails with any error except tfe.ErrResourceNotFound. ErrResourceNotFound is intentionally tolerated (treated as 'no variables'), but all other failures — auth, permission, network, server error — surface here. This is the call that actually pulls the Terraform-category variables for the run.

Solutions

  1. Check the wrapped `%w` error: 403 means the token's team role lacks 'Variables: Read' on the workspace.
  2. Re-run `terraform login` and confirm the token belongs to a team with variable read permission.
  3. Retry the operation — transient 5xx/network failures on ListAll are common.
  4. If self-hosted TFE, verify the variables API endpoint is reachable and not rate-limited.
  5. Confirm the workspace is not in Local Execution mode (that path skips this call entirely).
Defensive patterns

Strategy: retry

Validate before calling

// Confirm the token can list variables before the run.
// (Requires the same TFE client; call in a pre-flight check.)
func canListVariables(c *tfe.Client, ctx context.Context, wsID string) error {
    _, err := c.Variables.List(ctx, wsID, nil)
    return err
}

Try / catch

// Distinguish ErrResourceNotFound (tolerated) from real errors.
vars, err := c.Variables.ListAll(ctx, wsID, nil)
if err != nil && err != tfe.ErrResourceNotFound {
    return fmt.Errorf("error loading variables: %w", err)
}

Prevention

When it happens

Trigger: ListAll paginates the workspace variables endpoint; it errors on 401/403 (token can read the workspace but not its variables), 5xx server error, transport timeout, or a malformed workspace ID passed through from getRemoteWorkspaceID. Local Execution mode workspaces never reach this call (they return early at line 200).

Common situations: Custom team role with 'read workspace' but not 'read variables'; token expired between the workspace read and the variable read; large variable set hitting a gateway timeout; TFE upgrade mid-session changing the API contract.

Related errors


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

Appendix: source

Thrown at internal/cloud/backend_context.go:208

		diags = diags.Append(fmt.Errorf("error finding remote workspace: %w", err))
		return nil, diags
	}

	w, err := b.fetchWorkspace(ctx, b.Organization, workspace)
	if err != nil {
		diags = diags.Append(fmt.Errorf("error loading workspace: %w", err))
		return nil, diags
	}

	if isLocalExecutionMode(w.ExecutionMode) {
		log.Printf("[TRACE] cloud: skipping variable fetch for workspace %s/%s (%s), workspace is in Local Execution mode", b.getRemoteWorkspaceName(workspace), b.Organization, remoteWorkspaceID)
		return nil, nil
	}

	log.Printf("[TRACE] cloud: retrieving variables from workspace %s/%s (%s)", b.getRemoteWorkspaceName(workspace), b.Organization, remoteWorkspaceID)
	tfeVariables, err := b.client.Variables.ListAll(ctx, remoteWorkspaceID, nil)
	if err != nil && err != tfe.ErrResourceNotFound {
		diags = diags.Append(fmt.Errorf("error loading variables: %w", err))
		return nil, diags
	}

	result := make(map[string]arguments.UnparsedVariableValue)
	if tfeVariables != nil {
		for _, v := range tfeVariables.Items {
			if v.Category == tfe.CategoryTerraform {
				result[v.Key] = &remoteStoredVariableValue{
					definition: v,
				}
			}
		}
	}

	return result, nil
}

// remoteStoredVariableValue is a backendrun.UnparsedVariableValue implementation

View on GitHub (pinned to d32a084675)