Skip to content

fix: use deterministic hash for ETag generation#569

Open
awanawana wants to merge 1 commit intolong2ice:mainfrom
awanawana:fix/deterministic-etag
Open

fix: use deterministic hash for ETag generation#569
awanawana wants to merge 1 commit intolong2ice:mainfrom
awanawana:fix/deterministic-etag

Conversation

@awanawana
Copy link

Summary

Fixes #400

Python's built-in hash() function is salted by default (via PYTHONHASHSEED), which means it produces different values:

  • Across different Python processes
  • After service restart
  • Between multiple backends behind a load balancer

This causes ETags to change unexpectedly, invalidating browser caches and making the cache mechanism effectively useless in distributed deployments.

Changes

Replace hash() with hashlib.md5() for ETag generation:

def _compute_etag(data: bytes) -> str:
    """Compute a deterministic ETag hash from cache data."""
    return hashlib.md5(data).hexdigest()

MD5 is chosen for speed since this is for caching (not security). The hash is consistent across processes and restarts.

Before/After

Before (unpredictable across processes):

ETag: W/-4586327899234  # Process 1
ETag: W/8923847234987   # Process 2 (same data, different hash)

After (deterministic):

ETag: W/d41d8cd98f00b204e9800998ecf8427e  # Process 1
ETag: W/d41d8cd98f00b204e9800998ecf8427e  # Process 2 (same data, same hash)

🤖 Generated with Claude Code

Python's built-in hash() is salted by default (PYTHONHASHSEED),
producing different values across processes. This causes ETags to
change on service restart or differ between backends behind a load
balancer, invalidating the cache unexpectedly.

Replace hash() with hashlib.md5() which produces consistent values.
MD5 is used for speed since this is for caching, not security.

Fixes long2ice#400

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unstable ETag because of hash rantomisation

1 participant