hashicorp/terraform · error
error creating multipart upload
Error message
error creating multipart upload: %s
What it means
CreateMultipartUpload — the call that opens a multipart upload session — failed. Same auth/encryption surface as PutObject (309) but on the multipart-init API. Note: the fallback to single-part (client.go:147) only triggers when dataSize ≤ MaxFilePartSize; otherwise this error propagates.
Solutions
- Verify the principal can call CreateMultipartUpload (OBJECT_CREATE on the bucket).
- Confirm kms_key_id / SSE-C fields are consistent and the key is active.
- Confirm the bucket still exists and is in the configured namespace/compartment.
- For dataSize ≤ MaxFilePartSize the code will fall back to single-part upload; for larger sizes, resolve the multipart-init failure before retrying.
Example fix
// before: large state with KMS key the runner cannot use
// dataSize > DefaultFilePartSize -> multiPartUploadImpl -> 316
// after: point at an active key in an accessible compartment
backend "oci" { kms_key_id = var.active_kms_key_ocid } Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: verify CreateMultipartUpload will succeed for this principal
func canMultipart(c *RemoteClient) error {
req := objectstorage.CreateMultipartUploadRequest{
NamespaceName: common.String(c.namespace),
BucketName: common.String(c.bucketName),
CreateMultipartUploadDetails: objectstorage.CreateMultipartUploadDetails{
Object: common.String(c.path + ".probe"),
},
}
if c.kmsKeyID != "" { req.OpcSseKmsKeyId = common.String(c.kmsKeyID) }
resp, err := c.objectStorageClient.CreateMultipartUpload(context.Background(), req)
if err != nil { return err }
abort := objectstorage.AbortMultipartUploadRequest{UploadId: resp.UploadId, NamespaceName: resp.Namespace, BucketName: resp.Bucket, ObjectName: resp.Object}
_, _ = c.objectStorageClient.AbortMultipartUpload(context.Background(), abort)
return nil
} Type guard
func isServiceError(err error) (common.ServiceError, bool) {
var se common.ServiceError
return se, errors.As(err, &se)
} Try / catch
// Retry 5xx/429 on multipart init; surface 4xx for config fixes
for i := 0; i < 3; i++ {
resp, err := client.CreateMultipartUpload(ctx, *req)
if err == nil { return resp, nil }
var se common.ServiceError
if errors.As(err, &se) && (se.GetHTTPStatusCode() == 429 || se.GetHTTPStatusCode() >= 500) {
time.Sleep(backoff(i)); continue
}
return resp, err
} Prevention
- Confirm the principal can call CreateMultipartUpload before relying on large-state uploads.
- Keep kms_key_id / SSE-C config consistent with the single-part path.
- For dataSize ≤ MaxFilePartSize, the backend falls back to single-part — keep that path healthy too.
- Document that large states also need the multipart-init permission, not just PutObject.
When it happens
Trigger: IAM lacks permission to create multipart uploads; KMS key invalid or in an inaccessible compartment; SSE-C customer key misconfigured; bucket deleted; 5xx on the service.
Common situations: KMS key rotated; SSE-C and SSE-KMS both partially set; cross-compartment bucket without the right policy; transient OCI incident.
Related errors
- failed to access object
- failed to upload object
- error reading source block
- error splitting data into parts
- error splitting source data
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/d5594074e84876cc.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/oci/multipart_upload.go:79
multipartUploadRequest := &objectstorage.CreateMultipartUploadRequest{
NamespaceName: common.String(multipartUploadData.client.namespace),
BucketName: common.String(multipartUploadData.client.bucketName),
RequestMetadata: multipartUploadData.RequestMetadata,
CreateMultipartUploadDetails: objectstorage.CreateMultipartUploadDetails{
Object: common.String(multipartUploadData.client.path),
},
}
if multipartUploadData.client.kmsKeyID != "" {
multipartUploadRequest.OpcSseKmsKeyId = common.String(multipartUploadData.client.kmsKeyID)
} else if multipartUploadData.client.SSECustomerKey != "" && multipartUploadData.client.SSECustomerKeySHA256 != "" {
multipartUploadRequest.OpcSseCustomerKey = common.String(multipartUploadData.client.SSECustomerKey)
multipartUploadRequest.OpcSseCustomerKeySha256 = common.String(multipartUploadData.client.SSECustomerKeySHA256)
multipartUploadRequest.OpcSseCustomerAlgorithm = common.String(multipartUploadData.client.SSECustomerAlgorithm)
}
multipartUploadResponse, err := multipartUploadData.client.objectStorageClient.CreateMultipartUpload(context.Background(), *multipartUploadRequest)
if err != nil {
return fmt.Errorf("error creating multipart upload: %s", err)
}
workerCount := defaultNumberOfGoroutines
osUploadPartResponses := make(chan objectStorageUploadPartResponse, len(sourceBlocks))
sourceBlocksChan := make(chan objectStorageSourceBlock, len(sourceBlocks))
wg := &sync.WaitGroup{}
wg.Add(len(sourceBlocks))
// Push all source blocks into the channel
for _, sourceBlock := range sourceBlocks {
sourceBlocksChan <- sourceBlock
}
close(sourceBlocksChan)
errChan := make(chan error, workerCount)
// Start workers
for i := 0; i < workerCount; i++ {
go func() {View on GitHub (pinned to d32a084675)