{"record":{"id":"6faff8e797a2e816","repo":"hashicorp/terraform","slug":"failed-to-write-state-w","errorCode":null,"errorMessage":"failed to write state: %w","messagePattern":"failed to write state: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/local/backend_refresh.go","lineNumber":112,"sourceCode":"\t\tnewState, refreshDiags = lr.Core.Refresh(lr.Config, lr.InputState, lr.PlanOpts)\n\t\tlog.Printf(\"[INFO] backend/local: refresh calling Refresh\")\n\t}()\n\n\tif b.opWait(doneCh, stopCtx, cancelCtx, lr.Core, opState, op.View) {\n\t\treturn\n\t}\n\n\t// Write the resulting state to the running op\n\trunningOp.State = newState\n\tdiags = diags.Append(refreshDiags)\n\tif refreshDiags.HasErrors() {\n\t\top.ReportResult(runningOp, diags)\n\t\treturn\n\t}\n\n\terr := statemgr.WriteAndPersist(opState, newState, schemas)\n\tif err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"failed to write state: %w\", err))\n\t\top.ReportResult(runningOp, diags)\n\t\treturn\n\t}\n\n\t// Show any remaining warnings before exiting\n\top.ReportResult(runningOp, diags)\n}\n","sourceCodeStart":94,"sourceCodeEnd":120,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/local/backend_refresh.go#L94-L120","documentation":"Thrown by Local.opRefresh after a successful refresh when statemgr.WriteAndPersist(opState, newState, schemas) returns a non-nil error while writing the refreshed state back to disk (or to the wrapped remote backend). The refresh itself succeeded; only persistence failed.","triggerScenarios":"WriteAndPersist returns err: the state file path is not writable, the disk is full, a remote backend PUT was rejected (e.g. size limit, lost permissions), or the state lock was released by a competing process. The error is appended to diags and reported via op.ReportResult.","commonSituations":"Out of disk space on the volume holding terraform.tfstate; a remote backend (S3, GCS, etc.) where the credentials lost write permission between plan and refresh; concurrent terraform runs racing on the same state file; antivirus locking the file on Windows during write.","solutions":["Free up disk space or move TF_DATA_DIR / the state path to a writable volume.","For remote backends, verify the credentials still have PutObject/storage.objectAdmin and that any state size cap (e.g. S3 object size, DynamoDB lock table) is not exceeded.","Ensure no other terraform process holds the state lock; rely on the StateLocker rather than disabling it.","Retry after fixing the underlying I/O issue; the refreshed state is in memory and can be re-persisted on the next run."],"exampleFix":"null","handlingStrategy":"retry","validationCode":"// Preflight: writable state target with free space.\nfunc stateWritable(path string) error {\n    dir := filepath.Dir(path)\n    var stat unix.Statfs_t\n    if err := unix.Statfs(dir, &stat); err != nil { return err }\n    if stat.Bavail*uint64(stat.Bsize) < 1<<20 { return fmt.Errorf(\"low disk space on %s\", dir) }\n    return os.WriteFile(filepath.Join(dir, \".wprobe\"), []byte{}, 0o644)\n}","typeGuard":"null","tryCatchPattern":"err := statemgr.WriteAndPersist(opState, newState, schemas)\nif err != nil {\n    if isTransient(err) { // retry once after backoff\n        time.Sleep(500 * time.Millisecond)\n        err = statemgr.WriteAndPersist(opState, newState, schemas)\n    }\n    if err != nil { diags = diags.Append(fmt.Errorf(\"failed to write state: %w\", err)) }\n}","preventionTips":["Ensure the volume holding the state path has free space and is writable.","For remote backends, confirm the principal still has object-write permission before refresh.","Never disable the StateLocker to 'work around' lock errors; fix the contention instead."],"tags":["local-backend","state","refresh","persistence","io"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}