Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/v1.15/BUG FIXES-20251223-184516.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: BUG FIXES
body: 'backend: Fix nil pointer dereference crash during `terraform init -migrate-state` when the destination backend returns a permission error'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
body: 'backend: Fix nil pointer dereference crash during `terraform init -migrate-state` when the destination backend returns a permission error'
body: 'backend: Fix nil pointer dereference crash during `terraform init` when the destination backend returns an error'

As far as I can tell this is reproducible without the flag and applies to any kind of error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will address this in #38033

time: 2025-12-23T18:45:16.000000Z
custom:
Issue: "38027"
56 changes: 31 additions & 25 deletions internal/command/meta_backend_migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,37 +282,43 @@ func (m *Meta) backendMigrateState_s_s(opts *backendMigrateOpts) error {

var err error
destinationState, sDiags := opts.Destination.StateMgr(opts.destinationWorkspace)
if sDiags.HasErrors() && sDiags.Err().Error() == backend.ErrDefaultWorkspaceNotSupported.Error() {
// If the backend doesn't support using the default state, we ask the user
// for a new name and migrate the default state to the given named state.
destinationState, err = func() (statemgr.Full, error) {
log.Print("[TRACE] backendMigrateState: destination doesn't support a default workspace, so we must prompt for a new name")
name, err := m.promptNewWorkspaceName(opts.DestinationType)
if err != nil {
return nil, err
}
if sDiags.HasErrors() {
if sDiags.Err().Error() == backend.ErrDefaultWorkspaceNotSupported.Error() {
// If the backend doesn't support using the default state, we ask the user
// for a new name and migrate the default state to the given named state.
destinationState, err = func() (statemgr.Full, error) {
log.Print("[TRACE] backendMigrateState: destination doesn't support a default workspace, so we must prompt for a new name")
name, err := m.promptNewWorkspaceName(opts.DestinationType)
if err != nil {
return nil, err
}

// Update the name of the destination state.
opts.destinationWorkspace = name
// Update the name of the destination state.
opts.destinationWorkspace = name

destinationState, sDiags := opts.Destination.StateMgr(opts.destinationWorkspace)
if sDiags.HasErrors() {
return nil, sDiags.Err()
}
destinationState, sDiags := opts.Destination.StateMgr(opts.destinationWorkspace)
if sDiags.HasErrors() {
return nil, sDiags.Err()
}

// Ignore invalid workspace name as it is irrelevant in this context.
workspace, _ := m.Workspace()
// Ignore invalid workspace name as it is irrelevant in this context.
workspace, _ := m.Workspace()

// If the currently selected workspace is the default workspace, then set
// the named workspace as the new selected workspace.
if workspace == backend.DefaultStateName {
if err := m.SetWorkspace(opts.destinationWorkspace); err != nil {
return nil, fmt.Errorf("Failed to set new workspace: %s", err)
// If the currently selected workspace is the default workspace, then set
// the named workspace as the new selected workspace.
if workspace == backend.DefaultStateName {
if err := m.SetWorkspace(opts.destinationWorkspace); err != nil {
return nil, fmt.Errorf("Failed to set new workspace: %s", err)
}
}
}

return destinationState, nil
}()
return destinationState, nil
}()
} else {
// For any other error, return it immediately to avoid nil pointer dereference
return fmt.Errorf(strings.TrimSpace(
errMigrateSingleLoadDefault), opts.DestinationType, sDiags.Err())
}
}
if err != nil {
return fmt.Errorf(strings.TrimSpace(
Expand Down
Loading