FiloSottile/age · error

invalid checksum

Error message

invalid checksum

What it means

The final 6 data characters are a BCH checksum over the HRP and payload. If verifyChecksum fails, the string was corrupted or mistyped somewhere — the library cannot trust the decoded payload.

Source

Thrown at internal/bech32/bech32.go:173

		}
	}
	for p, c := range s[pos+1:] {
		// Fold ASCII explicitly. Unicode case folding can turn a non-ASCII
		// rune into a shorter valid charset member.
		if c >= 'A' && c <= 'Z' {
			c += 'a' - 'A'
		}
		d := strings.IndexRune(charset, c)
		if d == -1 {
			return "", nil, fmt.Errorf("invalid character data part: s[%d]=%v", p, c)
		}
		data = append(data, byte(d))
	}
	if len(data) < 6 {
		return "", nil, fmt.Errorf("data part too short")
	}
	if !verifyChecksum(hrp, data) {
		return "", nil, fmt.Errorf("invalid checksum")
	}
	data, err = convertBits(data[:len(data)-6], 5, 8, false)
	if err != nil {
		return "", nil, err
	}
	return hrp, data, nil
}

View on GitHub (pinned to b74dce4cdb)

Solutions

  1. Re-copy the original key exactly; do not hand-edit
  2. Fix single-character typos systematically (the checksum cannot suggest a correction)
  3. Confirm case handling: the string must be all-lowercase or all-uppercase
Defensive patterns

Strategy: validation

Validate before calling

// The library is the validator; pre-check case consistency at minimum:
if strings.ToLower(s) != s && strings.ToUpper(s) != s {
    return errors.New("mixed case bech32 input")
}

Prevention

When it happens

Trigger: Decode with any single-character typo, transposition, wrong-case HRP mismatch (checksum covers the HRP), or hand-edited key.

Common situations: Manual transcription of age keys, editing a key file by hand, mixed-case input where the HRP case doesn't match the checksum computation, network/markdown mangling of the string.

Related errors


AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31). Data as JSON: /api/errors/56b0c08c570a1106. Report an issue: GitHub.