{"record":{"id":"00e42de86a5ef8a3","repo":"hashicorp/terraform","slug":"failed-to-commit-multipart-upload-s","errorCode":null,"errorMessage":"failed to commit multipart upload: %s","messagePattern":"failed to commit multipart upload: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/oci/multipart_upload.go","lineNumber":163,"sourceCode":"\t\t\tlogger.Error(fmt.Sprintf(\"Failed to abort multipart upload: %s\", abortErr))\n\t\t}\n\t\treturn fmt.Errorf(\"not all parts uploaded successfully, multipart upload aborted\")\n\t}\n\n\tcommitMultipartUploadRequest := objectstorage.CommitMultipartUploadRequest{\n\t\tUploadId:           multipartUploadResponse.MultipartUpload.UploadId,\n\t\tNamespaceName:      multipartUploadResponse.Namespace,\n\t\tBucketName:         multipartUploadResponse.Bucket,\n\t\tObjectName:         multipartUploadResponse.Object,\n\t\tOpcClientRequestId: multipartUploadResponse.OpcClientRequestId,\n\t\tRequestMetadata:    multipartUploadRequest.RequestMetadata,\n\t\tCommitMultipartUploadDetails: objectstorage.CommitMultipartUploadDetails{\n\t\t\tPartsToCommit: commitMultipartUploadPartDetails,\n\t\t},\n\t}\n\t_, err = multipartUploadData.client.objectStorageClient.CommitMultipartUpload(context.Background(), commitMultipartUploadRequest)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to commit multipart upload: %s\", err)\n\t}\n\n\treturn nil\n}\nfunc (m MultipartUploadData) objectMultiPartSplit() ([]objectStorageSourceBlock, error) {\n\tdataSize := int64(len(m.Data))\n\toffsets, partSize, err := SplitSizeToOffsetsAndLimits(dataSize)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error splitting data into parts: %s\", err)\n\t}\n\tsourceBlocks := make([]objectStorageSourceBlock, len(offsets))\n\tfor i := range offsets {\n\t\tstart := offsets[i]\n\t\tend := start + partSize\n\t\tif end > dataSize {\n\t\t\tend = dataSize\n\t\t}\n\t\tsourceBlocks[i] = objectStorageSourceBlock{","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/oci/multipart_upload.go#L145-L181","documentation":"The final CommitMultipartUpload call failed after all parts uploaded successfully. The object is not finalized. Notably, on this failure path the code does NOT call AbortMultipartUpload — the multipart upload is left open, which can leak storage until lifecycle rules clean it up.","triggerScenarios":"Commit API returned 4xx (wrong/missing part etag, part list misaligned) or 5xx (transient service failure, throttling); a part's ETag was stale by commit time; auth expired between upload and commit.","commonSituations":"Transient 5xx at commit; throttling under high concurrency; long uploads whose token expired before commit; mismatched part list after retries.","solutions":["Inspect the wrapped error's OCI code via errors.As(common.ServiceError) — OpcRequestId and code pinpoint the commit failure.","Retry the whole Put once the root cause is addressed (the uncommitted multipart upload on the failed attempt will linger).","Configure a bucket lifecycle rule to expire Incomplete/Uncommitted Multipart Uploads so failed commits do not leak storage.","Consider patching the backend to call AbortMultipartUpload on this path (currently missing) to avoid manual cleanup."],"exampleFix":"// before: commit fails, leaves an open multipart upload that leaks storage\n//   return fmt.Errorf(\"failed to commit multipart upload: %s\", err)\n// after: abort on commit failure to avoid leaking the upload\n_, err = client.CommitMultipartUpload(ctx, commitReq)\nif err != nil {\n    abortReq := objectstorage.AbortMultipartUploadRequest{\n        UploadId: multipartUploadResponse.MultipartUpload.UploadId,\n        NamespaceName: multipartUploadResponse.Namespace,\n        BucketName: multipartUploadResponse.Bucket,\n        ObjectName: multipartUploadResponse.Object,\n    }\n    _ = client.AbortMultipartUpload(ctx, abortReq)\n    return fmt.Errorf(\"failed to commit multipart upload: %s\", err)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"func isCommitError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to commit multipart upload\")\n}","tryCatchPattern":"// On commit failure, abort the now-leaked multipart upload, then retry the Put\nif err := commit(); err != nil {\n    _ = abortMultipartUpload(multipartUploadResponse) // currently missing in source\n    return fmt.Errorf(\"failed to commit multipart upload: %w\", err)\n}","preventionTips":["Patch the backend to call AbortMultipartUpload on the commit-failure path (currently missing) — it leaks the upload otherwise.","Configure Object Storage lifecycle to expire Incomplete/Uncommitted Multipart Uploads automatically.","Inspect the wrapped OCI error code to distinguish 4xx (config) from 5xx (retry).","Refresh credentials before large uploads so the token survives until commit."],"tags":["oci","multipart-upload","cleanup","network"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}