mirror of
https://github.com/hashicorp/terraform.git
synced 2026-02-03 20:50:59 -05:00
v1.14 backport: Fix nil pointer dereference in backend state migration (#38028) (#38058)
Some checks are pending
build / Determine intended Terraform version (push) Waiting to run
build / Determine Go toolchain version (push) Waiting to run
build / Generate release metadata (push) Blocked by required conditions
build / Build for freebsd_386 (push) Blocked by required conditions
build / Build for linux_386 (push) Blocked by required conditions
build / Build for openbsd_386 (push) Blocked by required conditions
build / Build for windows_386 (push) Blocked by required conditions
build / Build for darwin_amd64 (push) Blocked by required conditions
build / Build for freebsd_amd64 (push) Blocked by required conditions
build / Build for linux_amd64 (push) Blocked by required conditions
build / Build for openbsd_amd64 (push) Blocked by required conditions
build / Build for solaris_amd64 (push) Blocked by required conditions
build / Build for windows_amd64 (push) Blocked by required conditions
build / Build for freebsd_arm (push) Blocked by required conditions
build / Build for linux_arm (push) Blocked by required conditions
build / Build for darwin_arm64 (push) Blocked by required conditions
build / Build for linux_arm64 (push) Blocked by required conditions
build / Build Docker image for linux_386 (push) Blocked by required conditions
build / Build Docker image for linux_amd64 (push) Blocked by required conditions
build / Build Docker image for linux_arm (push) Blocked by required conditions
build / Build Docker image for linux_arm64 (push) Blocked by required conditions
build / Build e2etest for linux_386 (push) Blocked by required conditions
build / Build e2etest for windows_386 (push) Blocked by required conditions
build / Build e2etest for darwin_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_amd64 (push) Blocked by required conditions
build / Build e2etest for windows_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_arm (push) Blocked by required conditions
build / Build e2etest for darwin_arm64 (push) Blocked by required conditions
build / Build e2etest for linux_arm64 (push) Blocked by required conditions
build / Run e2e test for linux_386 (push) Blocked by required conditions
build / Run e2e test for windows_386 (push) Blocked by required conditions
build / Run e2e test for darwin_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_amd64 (push) Blocked by required conditions
build / Run e2e test for windows_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_arm (push) Blocked by required conditions
build / Run e2e test for linux_arm64 (push) Blocked by required conditions
build / Run terraform-exec test for linux amd64 (push) Blocked by required conditions
Quick Checks / Unit Tests (push) Waiting to run
Quick Checks / Race Tests (push) Waiting to run
Quick Checks / End-to-end Tests (push) Waiting to run
Quick Checks / Code Consistency Checks (push) Waiting to run
Some checks are pending
build / Determine intended Terraform version (push) Waiting to run
build / Determine Go toolchain version (push) Waiting to run
build / Generate release metadata (push) Blocked by required conditions
build / Build for freebsd_386 (push) Blocked by required conditions
build / Build for linux_386 (push) Blocked by required conditions
build / Build for openbsd_386 (push) Blocked by required conditions
build / Build for windows_386 (push) Blocked by required conditions
build / Build for darwin_amd64 (push) Blocked by required conditions
build / Build for freebsd_amd64 (push) Blocked by required conditions
build / Build for linux_amd64 (push) Blocked by required conditions
build / Build for openbsd_amd64 (push) Blocked by required conditions
build / Build for solaris_amd64 (push) Blocked by required conditions
build / Build for windows_amd64 (push) Blocked by required conditions
build / Build for freebsd_arm (push) Blocked by required conditions
build / Build for linux_arm (push) Blocked by required conditions
build / Build for darwin_arm64 (push) Blocked by required conditions
build / Build for linux_arm64 (push) Blocked by required conditions
build / Build Docker image for linux_386 (push) Blocked by required conditions
build / Build Docker image for linux_amd64 (push) Blocked by required conditions
build / Build Docker image for linux_arm (push) Blocked by required conditions
build / Build Docker image for linux_arm64 (push) Blocked by required conditions
build / Build e2etest for linux_386 (push) Blocked by required conditions
build / Build e2etest for windows_386 (push) Blocked by required conditions
build / Build e2etest for darwin_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_amd64 (push) Blocked by required conditions
build / Build e2etest for windows_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_arm (push) Blocked by required conditions
build / Build e2etest for darwin_arm64 (push) Blocked by required conditions
build / Build e2etest for linux_arm64 (push) Blocked by required conditions
build / Run e2e test for linux_386 (push) Blocked by required conditions
build / Run e2e test for windows_386 (push) Blocked by required conditions
build / Run e2e test for darwin_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_amd64 (push) Blocked by required conditions
build / Run e2e test for windows_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_arm (push) Blocked by required conditions
build / Run e2e test for linux_arm64 (push) Blocked by required conditions
build / Run terraform-exec test for linux amd64 (push) Blocked by required conditions
Quick Checks / Unit Tests (push) Waiting to run
Quick Checks / Race Tests (push) Waiting to run
Quick Checks / End-to-end Tests (push) Waiting to run
Quick Checks / Code Consistency Checks (push) Waiting to run
* fix: handle all StateMgr errors during backend migration Fixes a nil pointer dereference panic that occurs during backend migration when StateMgr returns an error other than ErrDefaultWorkspaceNotSupported. The bug occurred because the code only checked for the specific ErrDefaultWorkspaceNotSupported error. When any other error occurred (such as permission errors like storage.objects.get access denied), destinationState remained nil, but the code continued and attempted to call destinationState.RefreshState(), causing a panic. This fix adds an else clause to catch and return all other errors from StateMgr, preventing the nil pointer dereference and providing users with a clear error message instead of a crash. Fixes #24100 * Add changelog entry for backend migration nil pointer fix 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Mark Hall <mark.hall993@gmail.com> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
1d06b6d1ac
commit
4aefefee4b
2 changed files with 40 additions and 29 deletions
5
.changes/v1.14/BUG FIXES-20251223-184516.yaml
Normal file
5
.changes/v1.14/BUG FIXES-20251223-184516.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
kind: BUG FIXES
|
||||
body: 'backend: Fix nil pointer dereference crash during `terraform init` when the destination backend returns an error'
|
||||
time: 2025-12-23T18:45:16.000000Z
|
||||
custom:
|
||||
Issue: "38027"
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
// Update the name of the destination state.
|
||||
opts.destinationWorkspace = name
|
||||
|
||||
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()
|
||||
|
||||
// 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 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
|
||||
}
|
||||
}
|
||||
|
||||
return destinationState, nil
|
||||
}()
|
||||
// Update the name of the destination state.
|
||||
opts.destinationWorkspace = name
|
||||
|
||||
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()
|
||||
|
||||
// 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
|
||||
}()
|
||||
} 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(
|
||||
|
|
|
|||
Loading…
Reference in a new issue