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
- Check the wrapped error and the preceding DEBUG log line `getObject <file>: error:` for the SDK's underlying cause.
- Verify COS credentials: ensure TENCENTCLOUD_SECRETID/TENCENTCLOUD_SECRETKEY (or backend `secret_id`/`secret_key`) are set, valid, and not expired.
- Confirm the bucket region and endpoint resolve: test `cos.<region>.myqcloud.com` reachability and TLS from the host running Terraform.
- 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
- Pin the COS backend `region` in the backend block so the endpoint always resolves.
- Inject credentials via env vars or a secret manager; never hardcode and never let them expire silently.
- Pre-flight a `cos:GetBucket` call from the host before `terraform init` to catch transport/auth issues early.
- Run Terraform from a network position with reliable outbound HTTPS to Tencent Cloud.
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
- failed to create bucket
- failed to delete bucket
- failed to delete file
- failed to save file to
- bucket not exists
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)