Loading...
Loading...
### Terraform Version Latest from main branch (as of 2025-12-23) ### Terraform Configuration Files ```hcl terraform { backend "gcs" { bucket = "my-terraform-state-bucket" prefix = "live/global/backend" } } ``` ### Expected Behavior When migrating from local backend to GCS backend, if the user lacks sufficient permissions (e.g., `storage.objects.get`), Terraform should display a clear error message indicating the permission issue. ### Actual Behavior Terraform crashes with a nil pointer dereference panic. ### Steps to Reproduce 1. Create a GCS bucket for Terraform state 2. Ensure your user has permission to create the bucket but NOT `storage.objects.get` permission (e.g., only has `storage.buckets.create`) 3. Configure a GCS backend in your Terraform configuration 4. Run `terraform init` to migrate from local state to GCS backend ### Crash Output ``` ❯ tf init -migrate-state Initializing the backend... !!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!! Terraform crashed! This is always indicative of a bug within Terraform. Please report the crash with Terraform[1] so that we can fix this. When reporting bugs, please include your terraform version, the stack trace shown below, and any additional information which may help replicate the issue. [1]: https://github.com/hashicorp/terraform/issues !!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!! panic: runtime error: invalid memory address or nil pointer dereference goroutine 1 [running]: runtime/debug.Stack() runtime/debug/stack.go:26 +0x64 github.com/hashicorp/terraform/internal/logging.PanicHandler() github.com/hashicorp/terraform/internal/logging/panic.go:84 +0x16c panic({0x105b0bbc0?, 0x107f97bd0?}) runtime/panic.go:783 +0x120 github.com/hashicorp/terraform/internal/command.(*Meta).backendMigrateState_s_s(0x140006fe000, 0x1400041cd90) github.com/hashicorp/terraform/internal/command/meta_backend_migrate.go:321 +0x768 github.com/hashicorp/terraform/internal/command.(*Meta).backendMigrateState(0x140006fe000, 0x1400041cd90) github.com/hashicorp/terraform/internal/command/meta_backend_migrate.go:138 +0x414 github.com/hashicorp/terraform/internal/command.(*Meta).backend_C_r_s(0x140006fe000, 0x140004fc500, 0x7828c893, 0x140007482a0, 0x1400067f418) github.com/hashicorp/terraform/internal/command/meta_backend.go:1215 +0xfe4 github.com/hashicorp/terraform/internal/command.(*Meta).backendFromConfig(0x140006fe000, 0x1400049f418) github.com/hashicorp/terraform/internal/command/meta_backend.go:780 +0xdd0 github.com/hashicorp/terraform/internal/command.(*Meta).Backend(0x140006fe000, 0x0?) github.com/hashicorp/terraform/internal/command/meta_backend.go:119 +0x60 github.com/hashicorp/terraform/internal/command.(*InitCommand).initBackend(0x140006fe000, {0x1061f4b50?, 0x140000fedc0?}, 0x1400070f9e0, {{0x1050446bd?, 0x1028b3fbc?}, 0x1400000f428?}, 0x48, {0x1061fb760, 0x1400011c110}) github.com/hashicorp/terraform/internal/command/init.go:360 +0xd80 github.com/hashicorp/terraform/internal/command.(*InitCommand).run(0x140006fe000, 0x140006380d0, {0x1061fb760, 0x1400011c110}) github.com/hashicorp/terraform/internal/command/init_run.go:185 +0xa90 github.com/hashicorp/terraform/internal/command.(*InitCommand).Run(0x140006fe000, {0x1400011a200?, 0x105be05a0?, 0x0?}) github.com/hashicorp/terraform/internal/command/init.go:74 +0x120 github.com/hashicorp/cli.(*CLI).Run(0x140003ea280) github.com/hashicorp/cli@v1.1.7/cli.go:265 +0x420 main.realMain() github.com/hashicorp/terraform/main.go:339 +0x1784 main.main() github.com/hashicorp/terraform/main.go:64 +0x1c ``` ### Root Cause In `internal/command/meta_backend_migrate.go` around line 284-323, the code calls `opts.Destination.StateMgr()` which can return errors in the diagnostics. However, the code only handles the specific case of `backend.ErrDefaultWorkspaceNotSupported`: ```go destinationState, sDiags := opts.Destination.StateMgr(opts.destinationWorkspace) if sDiags.HasErrors() && sDiags.Err().Error() == backend.ErrDefaultWorkspaceNotSupported.Error() { // Special handling for workspace not supported... } // No handling for OTHER errors - destinationState is nil! if err := destinationState.RefreshState(); err != nil { // <- CRASH: nil pointer dereference ``` When any error OTHER than `ErrDefaultWorkspaceNotSupported` occurs (such as permission errors, network errors, etc.), the code skips the if block, leaving `destinationState` as `nil`, then immediately tries to call `destinationState.RefreshState()`, causing the panic. ### Additional Context This is similar to #24100 which reported the same crash for the OSS backend. The root cause is identical - the code doesn't properly handle all error cases from `StateMgr()`. The bug affects any backend migration scenario where `StateMgr()` returns an error that isn't `ErrDefaultWorkspaceNotSupported`, including: - GCS backend with insufficient permissions (as shown here) - OSS backend (as reported in #24100) - Potentially other backends with similar error conditions ### Fix Available I have a fix ready that properly handles all errors from `StateMgr()` by adding an else clause to return the error immediately instead of allowing the code to continue with a nil `destinationState`. Will submit a PR shortly.
Click on a version to see all relevant bugs
Terraform Integration
Learn more about where this data comes from
Bug Scrub Advisor
Streamline upgrades with automated vendor bug scrubs
BugZero Enterprise
Wish you caught this bug sooner? Get proactive today.