hashicorp/terraform · error
failed to upload part
Error message
failed to upload part %d: %w
What it means
Thrown by uploadPartsWorker() when the OCI SDK's UploadPart API call fails for a specific part during multipart state upload. This is the most common multipart error — it wraps the underlying OCI SDK error (network failure, authentication issue, throttling, or service error) with the failing part number for diagnostics.
Solutions
- Check OCI IAM credentials — run 'oci os ns get' to verify the profile can access Object Storage.
- Verify the bucket exists and the IAM user has ObjectPutPart and ObjectManageReadAccess permissions.
- If using KMS (kms_key_id), ensure the key is enabled and the user has keys/Decrypt and keys/Encrypt permissions.
- Check network connectivity to Object Storage — add a Service Gateway to the VCN for OCI-native access.
- Retry the operation — transient throttling (429) or service errors (5xx) are common for large uploads.
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight check: verify OCI credentials and bucket access before multipart upload
func verifyOCIAccess(client *objectstorage.ObjectStorageClient, namespace, bucket string) error {
req := objectstorage.HeadBucketRequest{
NamespaceName: common.String(namespace),
BucketName: common.String(bucket),
}
_, err := client.HeadBucket(context.Background(), req)
return err
} Try / catch
// Retry UploadPart failures with exponential backoff
maxRetries := 3
for attempt := 0; attempt < maxRetries; attempt++ {
response, err = ctx.client.objectStorageClient.UploadPart(context.Background(), *uploadPartRequest)
if err == nil {
break
}
if attempt < maxRetries-1 {
time.Sleep(time.Duration(1<<attempt) * time.Second)
// Rebuild request body if needed — the reader may have been consumed
uploadPartRequest.UploadPartBody = io.NopCloser(bytes.NewReader(buffer))
}
} Prevention
- Verify OCI IAM credentials and Object Storage permissions before running Terraform.
- Configure a Service Gateway in the VCN for reliable, low-latency Object Storage access.
- Ensure KMS key IDs in the backend config are valid and accessible.
- Use OCI's default retry policy (already set via RequestMetadata in the upload data).
When it happens
Trigger: ctx.client.objectStorageClient.UploadPart(context.Background(), *uploadPartRequest) returns a non-nil error. The part request includes uploadId, object name, namespace, bucket, content length, body, and part number. Common triggers: expired session token, network timeout to OCI Object Storage, bucket not found, KMS key access denied, or SSE customer key mismatch.
Common situations: Transient network issues during large state uploads (>128MB). Expired or rotated OCI API keys. IAM policy missing objectstorage:ObjectPutPart permission. KMS key ID configured but not accessible. Running in a restricted network (corporate proxy, VCN without Service Gateway for Object Storage).
Related errors
- failed to access object HttpStatusCode
- failed to access object
- failed to commit multipart upload
- failed to upload part
- unable to read 'content' from response
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/fc371d6669bdfdfd.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/oci/multipart_upload.go:241
UploadPartBody: io.NopCloser(bytes.NewReader(buffer)),
UploadPartNum: block.blockNumber,
ContentMD5: common.String(base64.StdEncoding.EncodeToString(sum[:])),
RequestMetadata: common.RequestMetadata{
RetryPolicy: getDefaultRetryPolicy(),
},
}
if ctx.client.kmsKeyID != "" {
uploadPartRequest.OpcSseKmsKeyId = common.String(ctx.client.kmsKeyID)
} else if ctx.client.SSECustomerKey != "" && ctx.client.SSECustomerKeySHA256 != "" {
uploadPartRequest.OpcSseCustomerKey = common.String(ctx.client.SSECustomerKey)
uploadPartRequest.OpcSseCustomerKeySha256 = common.String(ctx.client.SSECustomerKeySHA256)
uploadPartRequest.OpcSseCustomerAlgorithm = common.String(ctx.client.SSECustomerAlgorithm)
}
response, err := ctx.client.objectStorageClient.UploadPart(context.Background(), *uploadPartRequest)
if err != nil {
ctx.errChan <- fmt.Errorf("failed to upload part %d: %w", *block.blockNumber, err)
return
}
ctx.osUploadPartResponses <- objectStorageUploadPartResponse{
response: response,
error: nil,
partNumber: block.blockNumber,
}
ctx.wg.Done()
}
}
View on GitHub (pinned to d32a084675)