hashicorp/terraform · error

failed to upload object

Error message

failed to upload object: %w

What it means

PutObject (single-part state upload) failed; the error is wrapped verbatim. Common OCI causes: 403 (no OBJECT_CREATE/OBJECT_OVERWRITE), invalid or inaccessible KMS key, SSE-C customer key mismatch against the bucket's default encryption, quota exceeded, or 5xx.

Solutions

  1. Verify the principal has OBJECT_CREATE and (for overwrite) OBJECT_OVERWRITE on the bucket.
  2. If using KMS, confirm kms_key_id points to an active key in an accessible compartment and that the principal can use it (inspectKey, encrypt/decrypt).
  3. If using SSE-C, confirm key/sha256/algorithm are consistent across reads and writes.
  4. Retry transient 5xx; the existing retry policy handles idempotent PutObject failures.

Example fix

// before: backend uses a KMS key the runner principal cannot use
terraform {
  backend "oci" { kms_key_id = "ocid1.key.oc1...old" }
}
// after: point at the active key the principal has encrypt/decrypt on
terraform {
  backend "oci" { kms_key_id = var.active_kms_key_ocid }
}
Defensive patterns

Strategy: retry

Validate before calling

// Verify write + KMS permissions before the first apply
func canWrite(c *RemoteClient) error {
    probe := objectstorage.PutObjectRequest{
        NamespaceName: common.String(c.namespace),
        BucketName:    common.String(c.bucketName),
        ObjectName:    common.String(c.path + ".probe"),
        PutObjectBody: io.NopCloser(bytes.NewReader([]byte("probe"))),
    }
    if c.kmsKeyID != "" { probe.OpcSseKmsKeyId = common.String(c.kmsKeyID) }
    _, err := c.objectStorageClient.PutObject(context.Background(), probe)
    if err != nil { _ = c.objectStorageClient.DeleteObject(context.Background(), objectstorage.DeleteObjectRequest{NamespaceName: probe.NamespaceName, BucketName: probe.BucketName, ObjectName: probe.ObjectName}) }
    return err
}

Type guard

func isOCIError(err error) (common.ServiceError, bool) {
    var se common.ServiceError
    return se, errors.As(err, &se)
}

Try / catch

// Retry transient 5xx/429 on PutObject; surface 4xx for config fixes
for i := 0; i < 3; i++ {
    err := c.uploadSinglePartObject(ctx, data, sum)
    if err == nil { break }
    var se common.ServiceError
    if errors.As(err, &se) && (se.GetHTTPStatusCode() == 429 || se.GetHTTPStatusCode() >= 500) {
        time.Sleep(backoff(i)); continue
    }
    return err
}

Prevention

When it happens

Trigger: IAM principal lacks OBJECT_CREATE/OBJECT_OVERWRITE; KMS key ID wrong, revoked, or in a different compartment the principal cannot use; SSE-C key rotated so writes now conflict with bucket default; object versioning/quota limits hit.

Common situations: Cross-team IAM change removed write permission; KMS key rotated but kms_key_id in backend config not updated; SSE-C and SSE-KMS both partially configured; bucket hard quota reached.

Related errors


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

Appendix: 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 d32a084675)