hashicorp/terraform · error
failed to access object
Error message
failed to access object '%s' in bucket '%s': %w
What it means
HeadObject returned a non-nil error that is not a 404 ServiceError, so the backend surfaces a wrapped generic access error. This is the metadata-fetch step of getObject; only 404 is treated as 'state not found, initialize'. Any other failure (auth, 403, 412, 5xx, transport, SSE-C mismatch) lands here.
Solutions
- If using SSE-C, confirm `sse_customer_key`, `sse_customer_key_sha256`, and `sse_customer_algorithm` match the key used to write the object.
- Verify the IAM principal has OBJECT_READ/OBJECT_INSPECT on the bucket and that namespace/bucket names are correct.
- For transient 5xx, retry — getDefaultRetryPolicy already retries idempotent reads but custom transport or non-retryable codes may bypass it.
- Check OCI service health for the objectstorage service in the region.
Example fix
// before: misconfigured SSE-C (key rotated, sha256 stale)
terraform {
backend "oci" {
bucket = "tf-state"
namespace = "idxx"
key = "prod.tfstate"
sse_customer_key = var.key // rotated
sse_customer_key_sha256 = var.old_sha // stale -> 303
}
}
// after: regenerate sha256 from the same key and pass both
terraform {
backend "oci" {
bucket = "tf-state"
namespace = "idxx"
key = "prod.tfstate"
sse_customer_key = var.key
sse_customer_key_sha256 = filesha256("sse.key") // matches
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate SSE-C config symmetry before any read
func validateSSEC(c *RemoteClient) error {
hasKey := c.SSECustomerKey != ""
hasSha := c.SSECustomerKeySHA256 != ""
if hasKey != hasSha {
return fmt.Errorf("SSE-C requires both sse_customer_key and sse_customer_key_sha256")
}
return nil
} Type guard
func isServiceError(err error) (common.ServiceError, bool) {
var se common.ServiceError
return se, errors.As(err, &se)
} Try / catch
if _, err := c.objectStorageClient.HeadObject(ctx, headRequest); err != nil {
var se common.ServiceError
if errors.As(err, &se) {
switch se.GetHTTPStatusCode() {
case 403: // fix IAM/SSE-C
case 404: // treat as not-found
}
}
// non-OCI transport error -> retry/backoff
} Prevention
- Keep SSE-C key and sha256 in sync (store both as a pair in your secret manager).
- Validate namespace and bucket name at backend config load.
- Grant the principal OBJECT_INSPECT/OBJECT_READ on the bucket.
- Use OCI service gateways to avoid public-internet transport failures.
When it happens
Trigger: Wrong SSE-C customer key/sha256 supplied (403/412 on a customer-encrypted object); IAM policy missing OBJECT_READ on the bucket; wrong namespace or bucket name; transient OCI 5xx; bucket deleted or in a different region.
Common situations: SSE-C key rotated and backend config not updated; instance principal missing the dynamic group/role; wrong `namespace` in backend config (namespace is tenancy-specific, not region); bucket renamed.
Related errors
- failed to access object HttpStatusCode
- failed to upload object
- error creating multipart upload
- failed to upload part
- failed to upload state
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/023ed4c28180cf48.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/oci/client.go:74
BucketName: common.String(c.bucketName),
RequestMetadata: common.RequestMetadata{
RetryPolicy: getDefaultRetryPolicy(),
},
}
if c.SSECustomerKey != "" && c.SSECustomerKeySHA256 != "" {
headRequest.OpcSseCustomerKey = common.String(c.SSECustomerKey)
headRequest.OpcSseCustomerKeySha256 = common.String(c.SSECustomerKeySHA256)
headRequest.OpcSseCustomerAlgorithm = common.String(c.SSECustomerAlgorithm)
}
// Get object from OCI
headResponse, headErr := c.objectStorageClient.HeadObject(ctx, headRequest)
if headErr != nil {
var ociHeadErr common.ServiceError
if errors.As(headErr, &ociHeadErr) && ociHeadErr.GetHTTPStatusCode() == 404 {
logger.Debug(" State file '%s' not found. Initializing Terraform state...", c.path)
return &remote.Payload{}, nil
} else {
return nil, fmt.Errorf("failed to access object '%s' in bucket '%s': %w", c.path, c.bucketName, headErr)
}
}
getRequest := objectstorage.GetObjectRequest{
NamespaceName: common.String(c.namespace),
ObjectName: common.String(c.path),
BucketName: common.String(c.bucketName),
IfMatch: headResponse.ETag,
RequestMetadata: common.RequestMetadata{
RetryPolicy: getDefaultRetryPolicy(),
},
}
if c.SSECustomerKey != "" && c.SSECustomerKeySHA256 != "" {
getRequest.OpcSseCustomerKey = common.String(c.SSECustomerKey)
getRequest.OpcSseCustomerKeySha256 = common.String(c.SSECustomerKeySHA256)
getRequest.OpcSseCustomerAlgorithm = common.String(c.SSECustomerAlgorithm)
}
// Get object from OCIView on GitHub (pinned to d32a084675)