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

  1. Re-download the object and recompute its MD5 out of band to confirm whether the stored bytes or the header is wrong.
  2. If the bytes are correct but the header is stale, re-upload the state through Terraform (`terraform state push`) so header and body agree.
  3. If the bytes are corrupted, restore from backup or a known-good state file, then push it back through the backend.
  4. 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

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


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)