{"record":{"id":"2c59f4ec3e6841d5","repo":"hashicorp/terraform","slug":"v-additionally-unlocking-the-state-in-kubern","errorCode":null,"errorMessage":"%v\n\t\t\t\tAdditionally, unlocking the state in Kubernetes failed:\n\n\t\t\t\tError message: %q\n\t\t\t\tLock ID (gen): %v\n\t\t\t\tSecret Name: %v\n\n\t\t\t\tYou may have to force-unlock this state in order to use it again.\n\t\t\t\tThe Kubernetes backend acquires a lock during initialization to ensure\n\t\t\t\tthe initial state file is created.","messagePattern":"(.+?)\n\t\t\t\tAdditionally, unlocking the state in Kubernetes failed:\n\n\t\t\t\tError message: %q\n\t\t\t\tLock ID \\(gen\\): (.+?)\n\t\t\t\tSecret Name: (.+?)\n\n\t\t\t\tYou may have to force-unlock this state in order to use it again\\.\n\t\t\t\tThe Kubernetes backend acquires a lock during initialization to ensure\n\t\t\t\tthe initial state file is created\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/backend/remote-state/kubernetes/backend_state.go","lineNumber":128,"sourceCode":"\t\tsecretName, err := c.createSecretName(0)\n\t\tif err != nil {\n\t\t\treturn nil, diags.Append(err)\n\t\t}\n\n\t\t// Local helper function so we can call it multiple places\n\t\tunlock := func(baseErr error) error {\n\t\t\tif err := stateMgr.Unlock(lockID); err != nil {\n\t\t\t\tconst unlockErrMsg = `%v\n\t\t\t\tAdditionally, unlocking the state in Kubernetes failed:\n\n\t\t\t\tError message: %q\n\t\t\t\tLock ID (gen): %v\n\t\t\t\tSecret Name: %v\n\n\t\t\t\tYou may have to force-unlock this state in order to use it again.\n\t\t\t\tThe Kubernetes backend acquires a lock during initialization to ensure\n\t\t\t\tthe initial state file is created.`\n\t\t\t\treturn fmt.Errorf(unlockErrMsg, baseErr, err.Error(), lockID, secretName)\n\t\t\t}\n\n\t\t\treturn baseErr\n\t\t}\n\n\t\tif err := stateMgr.WriteState(states.NewState()); err != nil {\n\t\t\tunlockErr := unlock(err)\n\t\t\treturn nil, diags.Append(unlockErr)\n\t\t}\n\t\tif err := stateMgr.PersistState(nil); err != nil {\n\t\t\tunlockErr := unlock(err)\n\t\t\treturn nil, diags.Append(unlockErr)\n\t\t}\n\n\t\t// Unlock, the state should now be initialized\n\t\tif err := unlock(nil); err != nil {\n\t\t\treturn nil, diags.Append(err)\n\t\t}","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/kubernetes/backend_state.go#L110-L146","documentation":"Compound error during k8s backend StateMgr init: the backend creates the initial empty state and if WriteState or PersistState fails, it attempts to release the lock via the unlock closure (backend_state.go:119-145). If unlocking ALSO fails, this multi-line message wraps the base error together with the unlock error, the generated lock ID, and the Secret name. It tells the operator the state is now locked and must be force-unlocked.","triggerScenarios":"WriteState fails (e.g., Secret write RBAC denied, etcd unavailable) AND the subsequent Unlock fails (e.g., lease update conflict, permissions). The state ends up locked with the generated lockID that the operator does not know.","commonSituations":"Insufficient RBAC for both Secret create and Lease update during initial provisioning; etcd/quorum issues during init; a race where the lease was modified between lock and unlock.","solutions":["Read the error for the generated Lock ID and Secret Name, then run 'terraform force-unlock <Lock ID>'.","Fix the RBAC so the service account can create Secrets and update Leases in the namespace.","Check etcd/API server health if writes are failing cluster-wide.","After force-unlock, re-run terraform init."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Parse the compound error to extract the Lock ID for force-unlock:\n// _, diags := b.StateMgr(name)\n// for _, d := range diags {\n//   msg := d.Description().Summary\n//   if strings.Contains(msg, \"unlocking the state in Kubernetes failed\") {\n//     lockID := extractLockID(msg) // regex 'Lock ID \\(gen\\): ([^\\s]+)')\n//     runTerraformForceUnlock(lockID)\n//   }\n// }","preventionTips":["Grant the backend service account RBAC to create Secrets and update Leases before first init.","Verify etcd/API server health before initializing the backend.","Keep the generated lock ID accessible until init succeeds so force-unlock is possible."],"tags":["kubernetes-backend","lock","force-unlock","init","compound-error"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}