{"record":{"id":"97df555c594cbdb6","repo":"hashicorp/terraform","slug":"failed-to-upload-state-w","errorCode":null,"errorMessage":"failed to upload state: %w","messagePattern":"failed to upload state: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/s3/client.go","lineNumber":240,"sourceCode":"\t\t\tinput.SSECustomerAlgorithm = aws.String(string(s3EncryptionAlgorithm))\n\t\t\tinput.SSECustomerKeyMD5 = aws.String(c.getSSECustomerKeyMD5())\n\t\t} else {\n\t\t\tinput.ServerSideEncryption = s3EncryptionAlgorithm\n\t\t}\n\t}\n\n\tif c.acl != \"\" {\n\t\tinput.ACL = s3types.ObjectCannedACL(c.acl)\n\t}\n\n\tlog.Info(\"Uploading remote state\")\n\n\tuploader := manager.NewUploader(c.s3Client, func(u *manager.Uploader) {\n\t\tu.ClientOptions = optFns\n\t})\n\t_, err := uploader.Upload(ctx, input)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to upload state: %w\", err)\n\t}\n\n\tif err := c.putMD5(ctx, sum[:]); err != nil {\n\t\t// if this errors out, we unfortunately have to error out altogether,\n\t\t// since the next Get will inevitably fail.\n\t\treturn fmt.Errorf(\"failed to store state MD5: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (c *RemoteClient) Delete() tfdiags.Diagnostics {\n\tvar diags tfdiags.Diagnostics\n\tctx := context.TODO()\n\tlog := c.logger(operationClientDelete)\n\n\tctx, baselog := baselogging.NewHcLogger(ctx, log)\n\tctx = baselogging.RegisterLogger(ctx, baselog)","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/s3/client.go#L222-L258","documentation":"Thrown in RemoteClient.put() (s3/client.go:240) when the S3 manager Uploader fails to PutObject the state file during a write. The wrapped (%w) error is the raw AWS SDK error. This aborts the state write; because the MD5 digest is written afterward, a failed upload means no digest row is created either.","triggerScenarios":"s3:PutObject denied; SSE-KMS key id invalid/unreachable or kms:Encrypt missing; bucket policy or Object Lock (WORM) blocking the write; S3 throttling; bucket in a different region than the client; wrong ACL string.","commonSituations":"Least-privilege role missing s3:PutObject; KMS key id typo or key disabled; Object Lock retention preventing overwrite; cross-account bucket without proper bucket-policy + KMS grants; ACL set to an unsupported value.","solutions":["Grant s3:PutObject on the state key (and kms:Encrypt/GenerateDataKey for SSE-KMS).","Verify the kms_key_id exists, is enabled, and is in the same region as the bucket.","Check for Object Lock / bucket policy denying the overwrite.","Retry on SlowDown/throttling with backoff."],"exampleFix":"// before: role can read but not write state\n\n// after\n// {\n//   \"Effect\": \"Allow\",\n//   \"Action\": [\"s3:PutObject\"],\n//   \"Resource\": \"arn:aws:s3:::mycorp-tfstate/*\"\n// }","handlingStrategy":"try-catch","validationCode":"// Probe write (and KMS) access before the apply writes state\n// _, err := s3Client.PutObject(ctx, &s3.PutObjectInput{Bucket:&bucket, Key:aws.String(\"tf-probe\"), Body: bytes.NewReader([]byte(\"{}\"))})\n// if err != nil { /* grant s3:PutObject / kms:Encrypt */ }","typeGuard":"// React by AWS error code on the wrapped upload error\n// var apiErr smithy.APIError\n// if errors.As(err, &apiErr) {\n//   switch apiErr.ErrorCode() {\n//   case \"AccessDenied\": /* s3:PutObject / kms:Encrypt */\n//   case \"SlowDown\":     /* retry */\n//   }\n// }","tryCatchPattern":"// Retry throttling, surface permission errors\n// var apiErr smithy.APIError\n// if errors.As(err, &apiErr) && apiErr.ErrorCode()==\"SlowDown\" { /* backoff retry */ } else { return err }","preventionTips":["Grant s3:PutObject on the state key and kms:Encrypt/GenerateDataKey for SSE-KMS.","Verify kms_key_id is valid, enabled, and same-region.","Check Object Lock / bucket policy won't block overwrites."],"tags":["s3","aws","permissions","iam","upload"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}