hashicorp/terraform · error
failed to access object HttpStatusCode
Error message
failed to access object HttpStatusCode: %d OpcRequestId: %s message: %s ErrorCode: %s
What it means
GetObject (the body fetch in the download path) failed with an error that satisfies errors.As for common.ServiceError. The backend prints the structured OCI failure: HTTP status, OPC request ID, message, and error code. This is the detailed counterpart to 305 and is the primary error for OCI-recognized failures (4xx/5xx from the service).
Solutions
- Copy the OpcRequestId and look it up in OCI Console > Governance > Audit / Object Storage diagnostics to pinpoint the failure.
- For HTTP 412, retry the full Get — the etag moved; the retry policy will re-Head and get a fresh etag only if the whole getObject is retried.
- For 401/403, refresh the principal/token (instance metadata, OCI config, session token) before retrying.
- For 429/5xx, reduce concurrency and apply backoff.
Example fix
// before: long apply whose pre-token expired or whose etag raced
// -> "failed to access object HttpStatusCode: 412 ... OpcRequestId: ABC"
// after: retry the read on 412 and refresh creds on 401/403
for attempt := 0; attempt < 3; attempt++ {
payload, err := client.Get()
if err == nil { break }
var se common.ServiceError
if errors.As(err, &se) && (se.GetHTTPStatusCode() == 412 || se.GetHTTPStatusCode() >= 500) {
time.Sleep(time.Duration(1<<attempt) * time.Second)
continue
}
return err
} Defensive patterns
Strategy: try-catch
Type guard
func serviceErrorOf(err error) (common.ServiceError, bool) {
var se common.ServiceError
return se, errors.As(err, &se)
} Try / catch
payload, err := c.objectStorageClient.GetObject(ctx, getRequest)
if err != nil {
var se common.ServiceError
if errors.As(err, &se) {
switch code := se.GetHTTPStatusCode(); {
case code == 412: // etag race -> re-Head and retry the whole getObject
case code == 401 || code == 403: // refresh creds
case code == 429 || code >= 500: // backoff and retry
}
}
} Prevention
- Avoid concurrent writers to the same workspace to prevent etag races (412).
- Refresh long-lived credentials before large state downloads.
- Capture OpcRequestId in logs for OCI-side lookup.
- Throttle CI concurrency against the same bucket to avoid 429s.
When it happens
Trigger: 412 Precondition Failed — the IfMatch etag from the prior HeadObject changed because another writer persisted state between the head and the get; 401/403 expired token or revoked permission; 429 throttling; 500/503 service errors; 409 conflicts.
Common situations: Two CI jobs writing state concurrently (etag races → 412); long-running apply whose token expired mid-run; throttling under high CI concurrency against the same bucket; OCI regional incident.
Related errors
- failed to access object
- failed to upload object
- failed to upload part
- failed to upload part
- unable to read 'content' from response
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/29779c6ff26f42c0.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/oci/client.go:97
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 OCI
getResponse, err := c.objectStorageClient.GetObject(ctx, getRequest)
if err != nil {
var ociErr common.ServiceError
if errors.As(err, &ociErr) {
return nil, fmt.Errorf("failed to access object HttpStatusCode: %d\nOpcRequestId: %s\n message: %s\n ErrorCode: %s", ociErr.GetHTTPStatusCode(), ociErr.GetOpcRequestID(), ociErr.GetMessage(), ociErr.GetCode())
}
return nil, fmt.Errorf("failed to access object '%s' in bucket '%s': %w", c.path, c.bucketName, err)
}
defer getResponse.Content.Close()
// Read object content
contentArray, err := io.ReadAll(getResponse.Content)
if err != nil {
return nil, fmt.Errorf("unable to read 'content' from response: %w", err)
}
// Compute MD5 hash
md5Hash := getResponse.ContentMd5
if md5Hash == nil || len(*md5Hash) == 0 {
md5Hash = getResponse.OpcMultipartMd5
}
// Construct payloadView on GitHub (pinned to d32a084675)