{"record":{"id":"a7125eb95ec26bf6","repo":"hashicorp/terraform","slug":"failed-to-upload-state-to-v-v","errorCode":null,"errorMessage":"Failed to upload state to %v: %v","messagePattern":"Failed to upload state to (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/gcs/client.go","lineNumber":77,"sourceCode":"\n\treturn result, diags\n}\n\nfunc (c *remoteClient) Put(data []byte) tfdiags.Diagnostics {\n\tvar diags tfdiags.Diagnostics\n\tctx := context.TODO()\n\terr := func() error {\n\t\tstateFileWriter := c.stateFile().NewWriter(ctx)\n\t\tif len(c.kmsKeyName) > 0 {\n\t\t\tstateFileWriter.KMSKeyName = c.kmsKeyName\n\t\t}\n\t\tif _, err := stateFileWriter.Write(data); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn stateFileWriter.Close()\n\t}()\n\tif err != nil {\n\t\treturn diags.Append(fmt.Errorf(\"Failed to upload state to %v: %v\", c.stateFileURL(), err))\n\t}\n\n\treturn diags\n}\n\nfunc (c *remoteClient) Delete() tfdiags.Diagnostics {\n\tvar diags tfdiags.Diagnostics\n\n\tctx := context.TODO()\n\tif err := c.stateFile().Delete(ctx); err != nil {\n\t\treturn diags.Append(fmt.Errorf(\"Failed to delete state file %v: %v\", c.stateFileURL(), err))\n\t}\n\n\treturn diags\n}\n\n// Lock writes to a lock file, ensuring file creation. Returns the generation\n// number, which must be passed to Unlock().","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/gcs/client.go#L59-L95","documentation":"Thrown by the remote client Put when writing or closing the state object writer fails. Put opens a NewWriter, optionally sets KMSKeyName, writes the data, and closes; any error in that sequence is wrapped with the state file URL.","triggerScenarios":"stateFileWriter.Write or stateFileWriter.Close returns an error — insufficient storage.objects.create permission, KMS key name invalid or inaccessible, bucket is versioning-locked, network error on upload, or bucket quota exceeded.","commonSituations":"Service account can read but not write; kms_encryption_key references a disabled or deleted Cloud KMS key; bucket has retention policy preventing overwrite; large state upload exceeds per-request limits; transient 5xx on upload.","solutions":["Grant roles/storage.objectAdmin (must include objects.create and objects.update).","If using kms_encryption_key, verify the key exists and the account has roles/cloudkms.cryptoKeyEncrypterDecrypter on it.","Check bucket retention policy / object versioning settings.","Retry transient upload failures; inspect the wrapped %v."],"exampleFix":"// before — read-only role\n// after\ngsutil iam ch serviceAccount:terraform@proj.iam.gserviceaccount.com:roles/storage.objectAdmin gs://tf-state","handlingStrategy":"validation","validationCode":"// Pre-flight: verify the account can write to the bucket.\n// gsutil cp /tmp/probe gs://bucket/.writeprobe && gsutil rm gs://bucket/.writeprobe\n// If kms_encryption_key set: gcloud kms keys describe ... and check encrypt/decrypt IAM.","typeGuard":null,"tryCatchPattern":"// Retry transient upload failures (5xx, connection reset).\nfor i := 0; i < 3; i++ {\n    err := put(data)\n    if err == nil { break }\n    if !isTransient(err) { return err }\n}","preventionTips":["Grant roles/storage.objectAdmin plus, when KMS is used, roles/cloudkms.cryptoKeyEncrypterDecrypter.","Check bucket retention/holding policies before writes.","Run writes from hosts with stable, high-bandwidth connectivity."],"tags":["gcs","backend","storage","iam","state-write","permissions"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}