{"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/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/kubernetes/backend_state.go#L110-L146","documentation":"During initial state creation the Kubernetes backend acquires a lock; if a subsequent WriteState/PersistState (or the final cleanup unlock) fails AND the compensating Unlock also fails, both errors are concatenated into this multi-line message. It tells the user the state may be left locked and points at force-unlock as the recovery path.","triggerScenarios":"StateMgr() (backend_state.go:100-148) finds no existing state, takes an init lock, then WriteState or PersistState fails (e.g. secret create/update API error); the deferred unlock() also fails (e.g. lease update conflict), so unlock() returns this composite error wrapping the original baseErr.","commonSituations":"Kubernetes API transient errors during the secret write for the initial empty state (RBAC, quota, etcd unavailable); the lease object was modified concurrently so the unlock Update hits a conflict; the lease was deleted out-of-band so the unlock's getLease/update fails.","solutions":["Run `terraform force-unlock <Lock ID (gen)>` using the Lock ID printed in the message to release the stale lock.","Resolve the underlying base error shown at the top of the message (e.g. RBAC/namespace/quota issues for Secret writes).","Verify the lease/secret names shown exist and are not held by another active run before force-unlocking.","Re-run `terraform init`/`terraform plan` once the lock is cleared and the base error is fixed."],"exampleFix":"# before - initial state write failed and left the state locked\nterraform init   # fails with the composite unlock error\n\n# after - release the stale lock, then re-run\nterraform force-unlock <Lock-ID-from-message>\nterraform init","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// After a failed init that may leave a k8s lock, parse the lock id and force-unlock\n_, diags := b.StateMgr(name)\nif diags.HasErrors() {\n    if lockID := extractLockID(diags.Err().Error()); lockID != \"\" {\n        // surface to user / run: terraform force-unlock <lockID>\n    }\n    return diags\n}","preventionTips":["Ensure the backend's service account has stable Secret/Lease create+update+get RBAC.","Avoid concurrent `terraform init` against the same fresh workspace.","Keep a runbook entry mapping this message to `terraform force-unlock <id>`."],"tags":["kubernetes","remote-state","locking","terraform-backend","force-unlock"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}