twpayne/chezmoi · error
RIPEMD-160 mismatch: expected %s, got %s
Error message
RIPEMD-160 mismatch: expected %s, got %s
What it means
Same verification flow as other checksums: if external.Checksum.RIPEMD160 is set in the external entry and ripemd160Sum(data) does not match the downloaded data, chezmoi emits this mismatch error. RIPEMD-160 is flagged as insecure and slated for removal, so a SHA256 checksum is recommended.
Source
Thrown at internal/chezmoi/sourcestate.go:1712
if external.Checksum.MD5 != nil {
s.warnFunc(
"%s: warning: insecure MD5 checksum will be removed, use a secure hash like SHA256 instead\n",
externalRelPath,
)
if gotMD5Sum := md5Sum(data); !bytes.Equal(gotMD5Sum, external.Checksum.MD5) {
err := fmt.Errorf("MD5 mismatch: expected %s, got %s", external.Checksum.MD5, hex.EncodeToString(gotMD5Sum))
errs = append(errs, err)
}
}
if external.Checksum.RIPEMD160 != nil {
s.warnFunc(
"%s: warning: insecure RIPEMD-160 checksum will be removed, use a secure hash like SHA256 instead\n",
externalRelPath,
)
if gotRIPEMD160Sum := ripemd160Sum(data); !bytes.Equal(gotRIPEMD160Sum, external.Checksum.RIPEMD160) {
format := "RIPEMD-160 mismatch: expected %s, got %s"
err := fmt.Errorf(format, external.Checksum.RIPEMD160, hex.EncodeToString(gotRIPEMD160Sum))
errs = append(errs, err)
}
}
if external.Checksum.SHA1 != nil {
s.warnFunc(
"%s: warning: insecure SHA1 checksum will be removed, use a secure hash like SHA256 instead\n",
externalRelPath,
)
if gotSHA1Sum := sha1Sum(data); !bytes.Equal(gotSHA1Sum, external.Checksum.SHA1) {
err := fmt.Errorf("SHA1 mismatch: expected %s, got %s", external.Checksum.SHA1, hex.EncodeToString(gotSHA1Sum))
errs = append(errs, err)
}
}
if external.Checksum.SHA256 != nil {
if gotSHA256Sum := sha256.Sum256(data); !bytes.Equal(gotSHA256Sum[:], external.Checksum.SHA256) {
format := "SHA256 mismatch: expected %s, got %s"View on GitHub (pinned to f901167e46)
Solutions
- Recompute with a RIPEMD-160 tool (e.g. openssl rmd160 file) and update checksum.ripemd160.
- Migrate the checksum to checksum.sha256, since RIPEMD-160 support will be removed.
- Verify the URL still points at the exact release/artifact you pinned.
- Remove the checksum if you accept unverified downloads.
Example fix
// before checksum.ripemd160 = "9c1185a5c5e9fc54612808977ee8f548" // after checksum.sha256 = "<sha256 of the downloaded file>"
Defensive patterns
Strategy: validation
Validate before calling
openssl rmd160 <downloaded-file> # Compare with checksum.ripemd160 before applying; prefer sha256 instead.
Try / catch
// Detect RIPEMD-160 mismatch in a wrapper and fail fast:
out, err := exec.Command("chezmoi", "apply").CombinedOutput()
if err != nil && strings.Contains(string(out), "RIPEMD-160 mismatch") {
return errors.New("refresh checksum.ripemd160 in .chezmoiexternal")
} Prevention
- Migrate legacy ripemd160 pins to sha256 now.
- Recompute digests from the exact bytes the URL serves.
- Beware hex vs base64 confusion when transcribing digests.
When it happens
Trigger: Fetching an external whose checksum.ripemd160 field was declared; the computed RIPEMD-160 digest of the downloaded bytes differs from the declared value.
Common situations: Legacy external configs copied from old dotfile repos; upstream file updated after the checksum was pinned; typo'd or hex/base64 confusion when transcribing the digest.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- MD5 mismatch: expected %s, got %s
- SHA1 mismatch: expected %s, got %s
- SHA256 mismatch: expected %s, got %s
- SHA384 mismatch: expected %s, got %s
- SHA512 mismatch: expected %s, got %s
AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01).
Data as JSON: /api/errors/480947ddf49023f4.
Report an issue: GitHub.