opentofu/opentofu · error

can't delete default state

Error message

can't delete default state

What it means

Returned by the S3 backend's DeleteWorkspace when the requested workspace name is "default" or empty. As with the Postgres backend, the default workspace is mandatory — it is the state addressed when no workspace is selected — so the name check short-circuits before any S3 call. There is no API path to delete the default workspace through this backend.

Source

Thrown at internal/backend/remote-state/s3/backend_state.go:118

	}

	parts = strings.SplitN(parts[1], "/", 2)

	if len(parts) < 2 {
		return ""
	}

	// not our key, so don't include it in our listing
	if parts[1] != b.keyName {
		return ""
	}

	return parts[0]
}

func (b *Backend) DeleteWorkspace(ctx context.Context, name string, _ bool) error {
	if name == backend.DefaultStateName || name == "" {
		return fmt.Errorf("can't delete default state")
	}

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

	return client.Delete(ctx)
}

// get a remote client configured for this state
func (b *Backend) remoteClient(name string) (*RemoteClient, error) {
	if name == "" {
		return nil, errors.New("missing state name")
	}

	client := &RemoteClient{
		s3Client:              b.s3Client,

View on GitHub (pinned to 3561785c48)

Solutions

  1. Skip `default` in any scripted deletion loop.
  2. To neutralize default's contents, destroy its resources (tofu destroy) instead of deleting the workspace.
  3. Create/switch to another workspace before deleting the one you intended.

Example fix

# before
for ws in $(tofu workspace list | tr -d '* '); do tofu workspace delete "$ws"; done

# after
for ws in $(tofu workspace list | tr -d '* '); do
  [ "$ws" = "default" ] && continue
  tofu workspace delete "$ws"
done
Defensive patterns

Strategy: validation

Validate before calling

for _, ws := range workspaces {
  if ws == "default" || ws == "" { continue }
  if err := b.DeleteWorkspace(ctx, ws, false); err != nil { return err }
}

Type guard

func isDefaultWorkspaceGuard(err error) bool {
  return err != nil && strings.Contains(err.Error(), "can't delete default state")
}

Try / catch

if err := b.DeleteWorkspace(ctx, name, false); err != nil {
  if strings.Contains(err.Error(), "can't delete default state") {
    // caller bug: adjust automation to never target default
  }
  return err
}

Prevention

When it happens

Trigger: `tofu workspace delete default`; automation that enumerates `tofu workspace list` and deletes each entry including the default one; direct calls to Backend.DeleteWorkspace with an empty string.

Common situations: Cleanup scripts and Makefile targets looping over workspaces; users trying to 'reset' a stack by deleting default.

Related errors


AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15). Data as JSON: /api/errors/f2df334360cd7ddb. Report an issue: GitHub.