router-for-me/CLIProxyAPI · critical
home ca fingerprint mismatch
Error message
home ca fingerprint mismatch
What it means
Thrown by verifyCACertificatePEM in internal/home/certificate.go when the SHA-256 fingerprint of the supplied CA PEM does not match the normalized expected fingerprint. This is a trust-on-first-use pin: the CA file on disk differs from the CA the deployment pinned. Note comparison is exact-string on the lowercased hex digest, so any byte difference in the certificate fails.
Source
Thrown at internal/home/certificate.go:194
func verifyCACertificateFile(path string, expectedFingerprint string) error {
raw, errRead := os.ReadFile(path)
if errRead != nil {
return errRead
}
return verifyCACertificatePEM(raw, expectedFingerprint)
}
func verifyCACertificatePEM(raw []byte, expectedFingerprint string) error {
actual, errFingerprint := certificateFingerprintPEM(raw)
if errFingerprint != nil {
return errFingerprint
}
expected := normalizeFingerprint(expectedFingerprint)
if expected == "" {
return fmt.Errorf("home ca fingerprint is required")
}
if actual != expected {
return fmt.Errorf("home ca fingerprint mismatch")
}
return nil
}
func certificateFingerprintPEM(raw []byte) (string, error) {
block, _ := pem.Decode(raw)
if block == nil || block.Type != "CERTIFICATE" {
return "", fmt.Errorf("home ca certificate pem is invalid")
}
cert, errParse := x509.ParseCertificate(block.Bytes)
if errParse != nil {
return "", errParse
}
sum := sha256.Sum256(cert.Raw)
return hex.EncodeToString(sum[:]), nil
}
func normalizeFingerprint(fingerprint string) string {View on GitHub (pinned to 78f0c4079e)
Solutions
- Recompute the fingerprint of the CA actually deployed: openssl x509 -in ca.pem -noout -fingerprint -sha256, and update ca-fingerprint in config
- If the CA was rotated legitimately, redistribute the new ca.pem and its fingerprint to all clients
- If the CA file is wrong, restore the original ca.pem that matches the pinned fingerprint
Example fix
# before home: ca-cert: /etc/cliproxy/ca.pem ca-fingerprint: "oldhash..." # after — after CA rotation home: ca-cert: /etc/cliproxy/new-ca.pem ca-fingerprint: "$(openssl x509 -in /etc/cliproxy/new-ca.pem -noout -fingerprint -sha256 | cut -d= -f2 | tr -d : | tr A-F a-f)"
Defensive patterns
Strategy: validation
Validate before calling
// pin check at startup, before the client relies on the CA
fp := strings.ToLower(hex.EncodeToString(certSHA256(caPEM)))
if fp != normalize(cfg.CAFingerprint) {
log.Fatalf("ca.pem fingerprint drift: file=%s pinned=%s — rotate config or restore ca.pem", fp, cfg.CAFingerprint)
} Try / catch
if err != nil && strings.Contains(err.Error(), "home ca fingerprint mismatch") {
// do NOT retry: trust mismatch requires operator decision (new fingerprint or restored CA)
haltAndAlert("home CA trust mismatch")
} Prevention
- Automate fingerprint updates whenever the CA is rotated (single pipeline for cert + hash)
- Alert on CA expiry so rotation is planned, not accidental
When it happens
Trigger: CA certificate file at the configured path was rotated, re-issued, or regenerated (different key) while the expected fingerprint stayed the same; wrong CA file copied into auths/ or the cert directory; fingerprint recorded from a different cert (e.g. leaf instead of CA).
Common situations: Home server rotated its CA and clients still pin the old fingerprint; staging fingerprint left in production config; someone re-ran the CA generation step and overwrote ca.pem; fingerprint copied with truncation or extra characters is handled by normalization but a wrong-hash is not.
Related errors
- home ca fingerprint is required
- home ca certificate pem is invalid
- home tls: ca-cert contains no PEM certificates
- client key pem is invalid
- client key is not rsa
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/8c5f68eb5507087c.
Report an issue: GitHub.