hashicorp/terraform · error

Invalid workspace name: The selected workspace described in

Error message

Invalid workspace name: The selected workspace described in %q has an invalid name. This suggests that the file contents were edited by something other than Terraform. To select a different, valid workspace name use commands `terraform workspace select` or `terraform workspace select -or-create`.

What it means

Returned by WorkspaceOverridden() when the on-disk workspace marker file (.terraform/environment by default) contains a workspace name that fails validWorkspaceName(). The message explicitly suspects the file was hand-edited, because Terraform only ever writes valid names to it. This guard is active in every backend-using command and can be selectively bypassed via bypassWorkspaceNameValidityCheck for recovery commands.

Source

Thrown at internal/command/meta.go:811

// whether the workspace is set by ENV or not.
func (m *Meta) WorkspaceOverridden() (string, bool, error) {
	if envVar := os.Getenv(WorkspaceNameEnvVar); envVar != "" {
		if !validWorkspaceName(envVar) {
			// Protect against invalid workspace names set via ENV.
			return "", true, errInvalidWorkspaceNameEnvVar
		}
		return envVar, true, nil
	}

	envData, err := os.ReadFile(filepath.Join(m.DataDir(), local.DefaultWorkspaceFile))
	current := string(bytes.TrimSpace(envData))
	if current == "" {
		current = backend.DefaultStateName
	}
	if !m.bypassWorkspaceNameValidityCheck && !validWorkspaceName(current) {
		// This check is active in every command that uses a backend.
		// It is selectively disabled in commands that are recommended for recovering from an invalid workspace.
		err := fmt.Errorf("Invalid workspace name: The selected workspace described in %q has an invalid name. This suggests that the file contents were edited by something other than Terraform. To select a different, valid workspace name use commands `terraform workspace select` or `terraform workspace select -or-create`.", filepath.Join(m.DataDir(), local.DefaultWorkspaceFile))
		return "", false, err
	}

	if err != nil && !os.IsNotExist(err) {
		// always return the default if we can't get a workspace name
		log.Printf("[ERROR] failed to read current workspace: %s", err)
	}

	return current, false, nil
}

// SetWorkspace saves the given name as the current workspace in the local
// filesystem.
func (m *Meta) SetWorkspace(name string) error {
	err := os.MkdirAll(m.DataDir(), 0755)
	if err != nil {
		return err
	}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Run `terraform workspace select <valid-name>` or `terraform workspace select <name> -or-create` to overwrite the corrupted file with a valid value.
  2. Inspect .terraform/environment and manually restore a known-good workspace name if select commands also fail.
  3. Delete the .terraform/environment file so Terraform falls back to the default workspace.

Example fix

# before: .terraform/environment contains "prod/us-east"
terraform plan
# after
terraform workspace select prod-us-east
terraform plan
Defensive patterns

Strategy: validation

Validate before calling

// Check the environment marker file before running terraform
envFile := filepath.Join(workdir, ".terraform", "environment")
if data, err := os.ReadFile(envFile); err == nil {
    name := strings.TrimSpace(string(data))
    if name != "" && !arguments.ValidWorkspaceName(name) {
        log.Fatalf("%s contains invalid workspace name %q", envFile, name)
    }
}

Prevention

When it happens

Trigger: The file at DataDir()/DefaultWorkspaceFile ('.terraform/environment') exists and its trimmed contents fail the workspace name validator. This occurs when an external tool, editor, or script corrupts the file contents.

Common situations: A sed/script that rewrote .terraform/environment with a slash-delimited name; a symlink or mount issue causing garbage contents; a merge conflict resolution that left conflict markers in the file; restoring a partial backup of .terraform/.

Related errors


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