hashicorp/terraform · warning

can't delete default state

Error message

can't delete default state

What it means

DeleteWorkspace() (backend_state.go:108-110) refuses to delete the workspace named backend.DefaultStateName ("default") or an empty name. This is an intentional guard so the always-present default state cannot be destroyed, which would orphan the bucket object namespace. It is a usage error, not a system fault.

Source

Thrown at internal/backend/remote-state/oss/backend_state.go:109

				options = append(options, oss.Marker(lastObj))
			}
			resp, err = bucket.ListObjects(options...)
			if err != nil {
				return nil, diags.Append(err)
			}
		} else {
			break
		}
	}
	sort.Strings(result[1:])
	return result, diags
}

func (b *Backend) DeleteWorkspace(name string, _ bool) tfdiags.Diagnostics {
	var diags tfdiags.Diagnostics

	if name == backend.DefaultStateName || name == "" {
		return diags.Append(fmt.Errorf("can't delete default state"))
	}

	client, err := b.remoteClient(name)
	if err != nil {
		return diags.Append(err)
	}
	return diags.Append(client.Delete())
}

func (b *Backend) StateMgr(name string) (statemgr.Full, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	client, err := b.remoteClient(name)
	if err != nil {
		return nil, diags.Append(err)
	}
	stateMgr := &remote.State{Client: client}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Exclude "default" from any scripted deletion loop.
  2. If you truly want the default state gone, delete the underlying OSS object and OTS digest row manually after removing all other workspaces.
  3. Pass a real non-default workspace name to terraform workspace delete.

Example fix

# before
for ws in $(terraform workspace list); do terraform workspace delete $ws; done

# after
for ws in $(terraform workspace list | grep -v '^* default$' | grep -v '^default$'); do
  terraform workspace delete "$ws"
done
Defensive patterns

Strategy: validation

Validate before calling

// Exclude 'default' from deletion lists in any wrapper script.
func deletable(name string) bool {
    return name != "" && name != "default"
}

Try / catch

// This is an intentional guard; the 'fix' is to not call it. Treat as no-op.
if err != nil && strings.Contains(err.Error(), "can't delete default state") {
    return nil // expected; skip
}

Prevention

When it happens

Trigger: Invoking terraform workspace delete default (or passing "" to DeleteWorkspace). The guard short-circuits before any OSS/OTS call.

Common situations: Scripted workspace cleanup that loops over all workspace names including "default"; CI trying to tear down every workspace; a tool wrapper that passes an empty name.

Related errors


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