hashicorp/terraform · error

failed to upload object: %w

Error message

failed to upload object: %w

What it means

Raised in uploadSinglePartObject when the OCI PutObject call fails. It wraps the raw SDK error returned by objectstorage.ObjectStorageClient.PutObject (client.go:193), so the underlying cause (auth, authorization, bucket-not-found, KMS key invalid, SSE-C mismatch, quota, throttling, network) is in the wrapped %w chain. This is the primary single-part state-write failure path.

Source

Thrown at internal/backend/remote-state/oci/client.go:195

		RequestMetadata: common.RequestMetadata{
			RetryPolicy: getDefaultRetryPolicy(),
		},
	}

	// Handle encryption settings
	if c.kmsKeyID != "" {
		putRequest.OpcSseKmsKeyId = common.String(c.kmsKeyID)
	} else if c.SSECustomerKey != "" && c.SSECustomerKeySHA256 != "" {
		putRequest.OpcSseCustomerKey = common.String(c.SSECustomerKey)
		putRequest.OpcSseCustomerKeySha256 = common.String(c.SSECustomerKeySHA256)
		putRequest.OpcSseCustomerAlgorithm = common.String(c.SSECustomerAlgorithm)
	}

	logger.Info(fmt.Sprintf("Uploading remote state: %s", c.path))

	putResponse, err := c.objectStorageClient.PutObject(ctx, putRequest)
	if err != nil {
		return fmt.Errorf("failed to upload object: %w", err)
	}

	logger.Info("Uploaded state file response: %+v\n", putResponse)
	return nil
}

func (c *RemoteClient) Delete() tfdiags.Diagnostics {
	var diags tfdiags.Diagnostics

	return diags.Append(c.DeleteAllObjectVersions())
}
func (c *RemoteClient) DeleteAllObjectVersions() error {
	request := objectstorage.ListObjectVersionsRequest{
		BucketName:    common.String(c.bucketName),
		NamespaceName: common.String(c.namespace),
		Prefix:        common.String(c.path),
		RequestMetadata: common.RequestMetadata{
			RetryPolicy: getDefaultRetryPolicy(),

View on GitHub (pinned to c9def3e214)

Solutions

  1. Unwrap the error and read the OCI ErrorCode: 403 -> add OBJECT_CREATE/OBJECT_OVERWRITE to the IAM policy; InvalidParameter -> fix the kms_key_id / SSE-C fields.
  2. Verify the KMS key id in the backend config is a valid OCID in the same region and that the principal has KEY_INSPECT/KEY_USE on it.
  3. If the bucket is immutable/retention-locked, confirm overwrite is allowed for the current clock and object age.
  4. For ContentMD5 mismatch (body corruption) re-run; if recurring, check memory/disk corruption or a tampering proxy.
  5. For throttling, reduce concurrent writers and rely on getDefaultRetryPolicy; sustained 429s need a limit increase.
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight checks before PutObject:
if c.kmsKeyID != "" && !strings.HasPrefix(c.kmsKeyID, "ocid1.key.ocid") {
    return fmt.Errorf("invalid kms_key_id: %s", c.kmsKeyID)
}
if len(data) == 0 { return fmt.Errorf("empty body") }
if ctx.Err() != nil { return ctx.Err() }

Type guard

var se common.ServiceError
if errors.As(err, &se) {
    switch se.GetHTTPStatusCode() {
    case 403: // need OBJECT_CREATE/OBJECT_OVERWRITE
    case 400: // InvalidParameter (bad KMS key / md5 mismatch)
    case 429: // throttled
    }
}

Try / catch

putResponse, err := c.objectStorageClient.PutObject(ctx, putRequest)
if err != nil {
    return fmt.Errorf("failed to upload object: %w", err)
}

Prevention

When it happens

Trigger: PutObject returns a non-nil error: 401/403 lacking OBJECT_CREATE/OBJECT_OVERWRITE, 400 when ContentMD5 (client.go:176) does not match the body (corruption in transit), 400 InvalidParameter for a bad KMS key id (OpcSseKmsKeyId), 412 If-Match conflicts, 429, or a 5xx/network error.

Common situations: KMS key id misconfigured or in a different region/tenancy; SSE-Customer key fields inconsistent; the bucket has immutability/worm retention blocking overwrite; insufficient IAM OBJECT_OVERWRITE permission; running out of storage quota; network reset during upload of a large single part.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/5b01dcff16081db2. Report an issue: GitHub.