hashicorp/terraform · error

failed to open file at

Error message

failed to open file at %v: %v

What it means

Emitted by getObject() in the COS backend when the COS SDK returns a nil response pointer (rsp==nil) from Object.Get. A nil response means the SDK never received an HTTP response — typically a transport-level failure (DNS, TLS, connection refused, timeout, bad credentials producing no body). The original SDK error is wrapped for context.

Solutions

  1. Check the wrapped error and the preceding DEBUG log line `getObject <file>: error:` for the SDK's underlying cause.
  2. Verify COS credentials: ensure TENCENTCLOUD_SECRETID/TENCENTCLOUD_SECRETKEY (or backend `secret_id`/`secret_key`) are set, valid, and not expired.
  3. Confirm the bucket region and endpoint resolve: test `cos.<region>.myqcloud.com` reachability and TLS from the host running Terraform.
  4. Retry the operation once transient network blips are ruled out; if using a proxy, ensure HTTPS_PROXY is set correctly.

Example fix

// before: backend configured without region, SDK cannot resolve endpoint
backend "cos" { bucket="tf-state"; secret_id="..."; secret_key="..." }
// after: supply region so the COS client URL is correct
backend "cos" { bucket="tf-state"; region="ap-guangzhou"; secret_id="..."; secret_key="..." }
Defensive patterns

Strategy: validation

Validate before calling

// Validate COS client reachability and credentials before running Terraform:
func cosClientWorks(ctx context.Context, client *cos.Client, bucket string) error {
    _, rsp, err := client.Bucket.Get(ctx, &cos.BucketGetOptions{Prefix: ""})
    if rsp == nil {
        return fmt.Errorf("transport failure reaching COS for bucket %s: %w", bucket, err)
    }
    rsp.Body.Close()
    if rsp.StatusCode >= 400 && rsp.StatusCode != 404 {
        return fmt.Errorf("COS returned status %d for bucket %s: %w", rsp.StatusCode, bucket, err)
    }
    return nil
}

Type guard

// Distinguish 'no response' (transport) from 'response with error' (HTTP)
func isTransportFailure(rsp *cos.Response, err error) bool {
    return rsp == nil && err != nil
}

Try / catch

err := backend.Configure(...)
// or after a Get/Put; if err contains 'failed to open file at' AND a network
// error type, classify as transient and retry with backoff:
if isTransportFailure(rsp, err) {
    backoff.Retry(func() error { /* reissue */ }, backoff.NewExponentialBackOff())
}

Prevention

When it happens

Trigger: c.cosClient.Object.Get(...) returns (nil, err) due to: network unreachable, invalid endpoint/region in the COS client URL, missing or expired SecretId/SecretKey, proxy interception dropping the connection, or SDK context cancellation before any response arrived.

Common situations: Misconfigured `region`/`endpoint` in the COS backend config; rotated Tencent Cloud API keys not updated in TF_* env vars or backend block; running Terraform from an environment without outbound internet access to `cos.<region>.myqcloud.com`; stale `cosContext` cancelled by a parent operation.

Related errors


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

Appendix: source

Thrown at internal/backend/remote-state/cos/client.go:186

		return nil, fmt.Errorf("lock file %s not exists", c.lockFile)
	}

	info := &statemgr.LockInfo{}
	if err := json.Unmarshal(data, info); err != nil {
		return nil, err
	}

	info.ID = checksum

	return info, nil
}

// getObject get remote object
func (c *remoteClient) getObject(cosFile string) (exists bool, data []byte, checksum string, err error) {
	rsp, err := c.cosClient.Object.Get(c.cosContext, cosFile, nil)
	if rsp == nil {
		log.Printf("[DEBUG] getObject %s: error: %v", cosFile, err)
		err = fmt.Errorf("failed to open file at %v: %v", cosFile, err)
		return
	}
	defer rsp.Body.Close()

	log.Printf("[DEBUG] getObject %s: code: %d, error: %v", cosFile, rsp.StatusCode, err)
	if err != nil {
		if rsp.StatusCode == 404 {
			err = nil
		} else {
			err = fmt.Errorf("failed to open file at %v: %v", cosFile, err)
		}
		return
	}

	checksum = rsp.Header.Get("X-Cos-Meta-Md5")
	log.Printf("[DEBUG] getObject %s: checksum: %s", cosFile, checksum)
	if len(checksum) != 32 {
		err = fmt.Errorf("failed to open file at %v: checksum %s invalid", cosFile, checksum)

View on GitHub (pinned to d32a084675)