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

  1. Copy the OpcRequestId and look it up in OCI Console > Governance > Audit / Object Storage diagnostics to pinpoint the failure.
  2. 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.
  3. For 401/403, refresh the principal/token (instance metadata, OCI config, session token) before retrying.
  4. 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

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


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 payload

View on GitHub (pinned to d32a084675)