Upload error: checksum mismatch (BadDigest / Content-MD5 did not match / XAmzContentSHA256Mismatch)
The server computed a different checksum for the data it received than the one your client declared, so it rejected the upload as corrupted.
Meaning
Integrity checks (Content-MD5, x-amz-checksum-*, x-amz-content-sha256, custom SHA-256 fields) catch data damaged in transit. S3 returns BadDigest (“The Content-MD5 you specified did not match what we received”) or XAmzContentSHA256Mismatch; GCS and other APIs have equivalents.
Most mismatches come from the client: hashing a different version of the data than was sent (before compression, re-encoding or newline conversion), or a stream that was partly consumed before upload.
Common causes
- Checksum computed over different bytes (before gzip, text-mode newline conversion, re-encoding)
- Stream partially read before upload, or retried without rewinding
- Network/proxy corruption or a truncated transfer
- Wrong encoding of the checksum (hex vs base64)
⚡ Quick fix
- Hash exactly the bytes you send, after any transformation
- Rewind or recreate the stream on retry
- Check whether the API wants base64 or hex
Detailed fix by platform
Node.js
- javascript
import { createHash } from 'node:crypto'; const md5 = createHash('md5').update(buf).digest('base64'); // Content-MD5 is base64, not hex await s3.putObject({ Bucket, Key, Body: buf, ContentMD5: md5 });
AWS CLI
aws s3 cp big.zip s3://bucket/ --checksum-algorithm SHA256
How to diagnose
- Values — Client vs server checksum
- Bytes — Hash computed before or after compression/encoding?
- Retries — Is the body stream reused?
🧠 Still stuck? Analyze your error
Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.
Report a correction or suggest an improvement
Last updated 7 Oct 2026