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

  1. Verify the principal can call CreateMultipartUpload (OBJECT_CREATE on the bucket).
  2. Confirm kms_key_id / SSE-C fields are consistent and the key is active.
  3. Confirm the bucket still exists and is in the configured namespace/compartment.
  4. 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

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


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)