shadowsocks/shadowsocks-windows · error · Exception
Sha256sum mismatch
Error message
Sha256sum mismatch
What it means
Thrown by GeositeUpdater after downloading a GeoSite database when the computed SHA-256 of the downloaded bytes does not equal the expected geositeSha256sum. It is an integrity check: the downloaded DB is considered corrupted or tampered and is not written to disk. The hash is compared in upper-case hex (BitConverter.ToString produces upper-case), so a case mismatch in the expected value would also trigger it.
Source
Thrown at shadowsocks-csharp/Controller/Service/GeositeUpdater.cs:134
logger.Info("Local GeoSite DB is up to date.");
UpdateCompleted?.Invoke(null, new GeositeResultEventArgs(false));
return;
}
}
// not latest. download new DB
var downloadedBytes = await httpClient.GetByteArrayAsync(geositeUrl);
// verify sha256sum
if (geositeVerifySha256)
{
byte[] downloadedDBHashBytes = mySHA256.ComputeHash(downloadedBytes);
string downloadedDBHash = BitConverter.ToString(downloadedDBHashBytes).Replace("-", String.Empty);
logger.Info($"Actual Sha256sum: {downloadedDBHash}");
if (geositeSha256sum != downloadedDBHash)
{
logger.Info("Sha256sum Verification: FAILED. Downloaded GeoSite DB is corrupted. Aborting the update.");
throw new Exception("Sha256sum mismatch");
}
else
{
logger.Info("Sha256sum Verification: PASSED. Applying to local GeoSite DB.");
}
}
// write to geosite file
using (FileStream geositeFileStream = File.Create(DATABASE_PATH))
await geositeFileStream.WriteAsync(downloadedBytes, 0, downloadedBytes.Length);
// update stuff
geositeDB = downloadedBytes;
LoadGeositeList();
bool pacFileChanged = MergeAndWritePACFile(config.geositeDirectGroups, config.geositeProxiedGroups, blacklist);
UpdateCompleted?.Invoke(null, new GeositeResultEventArgs(pacFileChanged));
}
catch (Exception ex)View on GitHub (pinned to 891d971682)
Solutions
- Retry the update once or twice (transient corruption or proxy interception often clears).
- Update geositeSha256sum to the hash published alongside the latest DB release so it matches the current upstream artifact.
- If running behind a corporate proxy, whitelist the geosite download host so it is not intercepted/rewritten.
- Temporarily disable geositeVerifySha256 only if you can confirm the source is trusted and integrity is verified another way.
Example fix
// before
if (geositeSha256sum != downloadedDBHash)
throw new Exception("Sha256sum mismatch");
// after: log both and retry before failing
logger.Info($"Expected: {geositeSha256sum}, Got: {downloadedDBHash}");
if (geositeSha256sum != downloadedDBHash)
throw new Exception($"Sha256sum mismatch (expected {geositeSha256sum}, got {downloadedDBHash})"); Defensive patterns
Strategy: retry
Validate before calling
// Pre-validate the expected hash format before comparing
if (string.IsNullOrEmpty(geositeSha256sum) || geositeSha256sum.Length != 64)
{ /* skip verification rather than compare against a bogus hash */ } Type guard
bool IsValidSha256Hex(string s) =>
!string.IsNullOrEmpty(s) && s.Length == 64 &&
s.All(c => (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')); Try / catch
for (int attempt = 0; attempt < 3; attempt++)
{
try { await UpdateGeosite(); break; }
catch (Exception ex) when (ex.Message == "Sha256sum mismatch")
{ if (attempt == 2) throw; await Task.Delay(2000 << attempt); }
} Prevention
- Publish the sha256 alongside the DB and update the expected hash in lockstep with the artifact.
- Compare hashes case-insensitively to avoid upper/lower hex mismatches.
- Retry transient download corruption before failing the whole update.
When it happens
Trigger: A network proxy or captive portal returning an HTML/redirect page instead of the DB bytes; a partial download due to a dropped connection that GetByteArrayAsync still completed; the upstream geositeUrl pointing at a file whose hash differs from geositeSha256sum (stale expected hash after a DB republish); a CDN serving a different version than the hash was computed against.
Common situations: The geositeSha256sum config was not updated after the upstream published a new DB; a transparent proxy or antivirus intercepting and rewriting the download; mirror/CDN inconsistency where different edges serve different versions; byte-for-byte truncation by an aggressive proxy.
AI-assisted analysis of shadowsocks/shadowsocks-windows@891d971682 (2026-08-13).
Data as JSON: /api/errors/38aec126cdab6a07.
Report an issue: GitHub.