Introduction
Hi, I'm miruky.
Amazon S3 validates an upload checksum independently before it accepts the object. This detects a byte-level mismatch in transit. The encoding matters: the S3 SHA-256 field uses the Base64 encoding of the 32 digest bytes, not the hexadecimal form printed by many local tools.
This Console run uploads one fixed 33-byte text file. I change one character in its SHA-256 value to prove that S3 rejects the mismatch, then retry with the correct value and verify the stored checksum on the object's Properties page.
The exercise stores one tiny object briefly and makes a few S3 requests. Review the current Amazon S3 pricing dimensions before running it; this article does not assume that every account or request is free.
For a production bucket, plan observability separately: CloudTrail data events can record object-level API activity, server access logging can retain request records, and CloudWatch request metrics can support operational alarms. I leave all three off in this short checksum run; data events and request metrics are billable, and delivered access-log objects incur normal storage charges.
1. Prepare the exact validation file
Create a local file named checksum-proof.txt with this one line:
checksum verification for miruky
The validation asset is exactly 33 UTF-8 bytes: the 32 visible ASCII characters plus one line-feed byte at the end. Its SHA-256 digest is:
Hex: 4120d7fe5bf95f8298810c223dd6d6640fb9fa89f3c09234a3537f3acd9962e3
Base64: QSDX/lv5X4KYgQwiPdbWZA+5+onzwJI0o1N/Os2ZYuM=
Use the Base64 value in the S3 form. The S3 checksum data type defines ChecksumSHA256 as a Base64-encoded 256-bit digest. This means Base64-encoding the hexadecimal text would produce the wrong value.
If an editor changes the line ending, adds a byte-order mark, or omits the final line feed, the checksum correctly changes and the precalculated-value upload should fail. Keep the file at 33 bytes before submitting either attempt.
2. Create a private general purpose bucket
I started with the AWS Console in English and fixed the Region before creating any S3 resource. The next crop records that selection without retaining the account menu.
The header confirms United States (N. Virginia) while the S3 Console is in English. This fixes the Region before the bucket and object are created.
Open Amazon S3 and search for miruky-bhkzetxxdnntnass. Confirm that the signed-in account has no exact bucket name before creation.
The exact filter for miruky-bhkzetxxdnntnass returns no bucket owned by the signed-in account. This exercise explicitly uses the global namespace, so a name already owned elsewhere in the AWS partition would still be rejected by the create form. Do not work around that result with a descriptive suffix.
Choose Create bucket. Under Bucket namespace, choose Global namespace. Enter miruky-bhkzetxxdnntnass, then select US East (N. Virginia) us-east-1. Keep Bucket owner enforced, all four Block Public Access settings, and default server-side encryption with Amazon S3 managed keys.
The crop shows Global namespace, miruky-bhkzetxxdnntnass, and US East (N. Virginia) us-east-1. The current bucket-creation guide distinguishes the global namespace from the account regional namespace; this run deliberately uses the global option. The lower ownership, public-access, and encryption sections are checked during validation but kept outside this image so unrelated fields cannot enter the article.
After creation, open the bucket and verify that it is empty. No versioning, website hosting, logging, replication, or public policy is needed for a checksum test.
The object list reports an empty bucket before the test. That baseline prevents an unrelated object from being mistaken for the checksum-validated upload.
3. Prove that one wrong checksum character fails
Choose Upload, add checksum-proof.txt, and verify the selected file size is 33.0 B. A different size means the local bytes do not match the published digest.
The selected-file row shows only checksum-proof.txt at 33.0 B. The byte count agrees with the locally audited asset before any network transfer.
Expand Properties. Under Checksums, change Checksum function from the current CRC64NVME (recommended) default to SHA256. In Precalculated value - optional, enter this deliberately wrong value; only its leading character differs from the expected checksum:
RSDX/lv5X4KYgQwiPdbWZA+5+onzwJI0o1N/Os2ZYuM=
The upload properties show SHA256 and RSDX/lv5X4KYgQwiPdbWZA+5+onzwJI0o1N/Os2ZYuM=. The expected digest begins with Q, so this request cannot pass byte-integrity validation.
Choose Upload. S3 calculates the checksum from the received bytes and compares it with the supplied value. AWS documents that a mismatch produces an error and the object is accepted only after the integrity check succeeds. This first upload should therefore fail.
The row reports Failed and Checksum mismatch for checksum-proof.txt. This is the negative control: the same file and algorithm are present, but one checksum character prevents a successful object write.
Exit the status page and return to the bucket. Confirm that checksum-proof.txt is still absent before retrying.
The object list remains empty. A failed checksum validation is not treated as a successfully stored object.
4. Retry with the exact SHA-256 value
Choose Upload, add the same audited 33-byte file, expand Properties, and return to Checksums. Change Checksum function to SHA256, then enter the correct Base64 value:
QSDX/lv5X4KYgQwiPdbWZA+5+onzwJI0o1N/Os2ZYuM=
The corrected upload pairs SHA256 with QSDX/lv5X4KYgQwiPdbWZA+5+onzwJI0o1N/Os2ZYuM=. This value matches the independently calculated digest character for character, including its trailing padding.
Choose Upload again.
The upload status is Succeeded for the one fixed object. URLs, request identifiers, and ETag metadata stay outside the crop.
Do not use the ETag as a substitute for this SHA-256 value. Whether an ETag is an MD5 digest depends on how the object was created and encrypted, so it is a separate piece of object metadata from this explicit SHA-256 checksum.
5. Verify the checksum stored with the object
Return to the uploaded object's detail page and locate its checksum properties. Compare the final crop with the independently calculated Base64 digest from the first section.
The checksum-only crop shows Checksum function as SHA256, Checksum type as Full object, and value QSDX/lv5X4KYgQwiPdbWZA+5+onzwJI0o1N/Os2ZYuM=. The preceding successful-upload row already identifies checksum-proof.txt, so the object header and its URL, ARN, owner, and timestamps stay outside this image. S3 stores the selected algorithm and checksum with the object, and the live row matches the independently calculated Base64 digest character for character.
Compare the value character for character, including +, /, and the trailing =. The successful precalculated upload and the stored object property provide two Console observations for the same digest.
Wrap-up
S3 rejected the 33-byte object when one checksum character was wrong, then accepted the same bytes after the supplied SHA-256 value matched. The object's Properties page exposed that stored checksum for later integrity verification.
Checksums verify bytes, not business meaning or trust in the source file. They are most useful when the expected digest comes from an independent, trusted build or publishing process.
Thanks for reading this far.
See you in the next one.
Disclosure: This article was written with AI assistance and independently verified against the linked primary sources and observed results.
References
- Checking object integrity for data uploads in Amazon S3
- Uploading objects
- Viewing object properties in the S3 Console
- Checksum data type
- Object data type and ETag behavior
- Amazon S3 data integrity protections
- Creating a general purpose bucket
- General purpose bucket naming rules
- Controlling ownership of objects and disabling ACLs
- Blocking public access to your Amazon S3 storage
- Configuring default encryption
- Amazon S3 CloudTrail events
- Enabling Amazon S3 server access logging
- Monitoring S3 metrics with CloudWatch
- Amazon S3 pricing











Top comments (0)