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

  1. Check OCI IAM credentials — run 'oci os ns get' to verify the profile can access Object Storage.
  2. Verify the bucket exists and the IAM user has ObjectPutPart and ObjectManageReadAccess permissions.
  3. If using KMS (kms_key_id), ensure the key is enabled and the user has keys/Decrypt and keys/Encrypt permissions.
  4. Check network connectivity to Object Storage — add a Service Gateway to the VCN for OCI-native access.
  5. 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

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


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)