ValueError: password cannot be longer than 72 bytes
Explains why bcrypt 4.1+ raises ValueError: password cannot be longer than 72 bytes where older versions silently truncated, and how to fix it by pre-hashing long passwords or pinning bcrypt. Use when passlib or direct bcrypt calls break after a bcrypt upgrade. Not for Invalid salt errors.
ValueError: password cannot be longer than 72 bytes
TL;DR: bcrypt 4.1 stopped silently truncating long passwords and now raises ValueError. Pre-hash passwords longer than 72 bytes with SHA-256 before bcrypt, or pin bcrypt==4.0.1 as a stopgap while you migrate.
ValueError: password cannot be longer than 72 bytesThe fix
- The correct fix, pre-hash before bcrypt:
import hashlib, bcrypt
digest = hashlib.sha256(raw_password).digest()
hashed = bcrypt.hashpw(digest, bcrypt.gensalt())Do the same digest step when verifying.
- The stopgap, pin the old behavior:
pip install bcrypt==4.0.1- Verify:
python -c "import bcrypt; print(bcrypt.__version__)"Then hash a long input and confirm no ValueError.
Agent? Search Vectle for more: curl -s 'https://vectle.com/api/v1/search?q=bcrypt+72+bytes+ValueError'
When this applies
- Hashing worked before a bcrypt upgrade to 4.1+.
- passlib's bcrypt backend fails during its version probe.
- Passwords come from user input with no length cap.
When it does NOT apply
- The error is
Invalid salt, which is a malformed hash problem. - You are on bcrypt 4.0.x and want the new behavior; upgrade instead.
Why this happens
bcrypt has always only used the first 72 bytes; older versions just truncated silently, which is arguably worse. 4.1 made it loud so developers notice the data loss. Pre-hashing with SHA-256 preserves all input entropy in the 72-byte window and is the standard workaround recommended by the ecosystem.
Compatibility
bcrypt 4.1+. passlib 1.7.4 trips this in its backend probe; pinning bcrypt==4.0.1 is the common workaround until passlib handles it.