hashicorp/terraform · error
failed to open file at
Error message
failed to open file at %v: checksum mismatch, %s != %s
What it means
Emitted by getObject() after a full body read when the MD5 computed from the downloaded bytes does not equal the `X-Cos-Meta-Md5` checksum stored on the object. This is an end-to-end integrity check failure — the data on the wire or at rest does not match what was originally written.
Solutions
- Re-download the object and recompute its MD5 out of band to confirm whether the stored bytes or the header is wrong.
- If the bytes are correct but the header is stale, re-upload the state through Terraform (`terraform state push`) so header and body agree.
- If the bytes are corrupted, restore from backup or a known-good state file, then push it back through the backend.
- Investigate the transport path (proxy, TLS terminator) if corruption recurs.
Example fix
// before: object body and X-Cos-Meta-Md5 disagree after an out-of-band edit // after: rewrite the object through the backend so checksum is recomputed // terraform state push terraform.tfstate
Defensive patterns
Strategy: validation
Validate before calling
// Independently verify object integrity before trusting the state
func verifyObjectIntegrity(ctx context.Context, client *cos.Client, key string) error {
rsp, err := client.Object.Get(ctx, key, nil)
if err != nil || rsp == nil { return err }
defer rsp.Body.Close()
stored := rsp.Header.Get("X-Cos-Meta-Md5")
data, err := ioutil.ReadAll(rsp.Body)
if err != nil { return err }
got := fmt.Sprintf("%x", md5.Sum(data))
if got != stored {
return fmt.Errorf("integrity mismatch for %s: body md5 %s != header %s; restore from backup and re-push", key, got, stored)
}
return nil
} Type guard
func integrityOK(storedHeader string, data []byte) bool {
return storedHeader == fmt.Sprintf("%x", md5.Sum(data))
} Try / catch
// Treat checksum mismatch as fatal, not retryable — escalating to restore
if strings.Contains(err.Error(), "checksum mismatch") {
return fmt.Errorf("state object corrupted; restore from backup and terraform state push: %w", err)
} Prevention
- Always write state through the backend so header and body agree.
- When migrating state, push it via `terraform state push` rather than byte-copying objects.
- Keep periodic backups of state so corruption is recoverable.
- Investigate any proxy or TLS terminator if mismatches recur.
When it happens
Trigger: check := hex(md5.Sum(data)) differs from the stored checksum header. Causes: silent corruption over the network (bit flips), a partially-overwritten object, an object that was rewritten with different content but the old metadata header, or a man-in-the-middle altering bytes.
Common situations: State object was overwritten out-of-band with new content but the X-Cos-Meta-Md5 header was not updated to match; network appliance mangling payload; rare storage-layer corruption; a botched migration that copied bytes but not metadata.
Related errors
- failed to open file at
- bucket not exists
- failed to create bucket
- failed to create tag
- failed to delete bucket
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/36281c8b414772a3.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/cos/client.go:219
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)
return
}
exists = true
data, err = ioutil.ReadAll(rsp.Body)
log.Printf("[DEBUG] getObject %s: data length: %d", cosFile, len(data))
if err != nil {
err = fmt.Errorf("failed to open file at %v: %v", cosFile, err)
return
}
check := fmt.Sprintf("%x", md5.Sum(data))
log.Printf("[DEBUG] getObject %s: check: %s", cosFile, check)
if check != checksum {
err = fmt.Errorf("failed to open file at %v: checksum mismatch, %s != %s", cosFile, check, checksum)
return
}
return
}
// putObject put object to remote
func (c *remoteClient) putObject(cosFile string, data []byte) error {
opt := &cos.ObjectPutOptions{
ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
XCosMetaXXX: &http.Header{
"X-Cos-Meta-Md5": []string{fmt.Sprintf("%x", md5.Sum(data))},
},
},
ACLHeaderOptions: &cos.ACLHeaderOptions{
XCosACL: c.acl,
},
}View on GitHub (pinned to d32a084675)