Skip to main content

Object checksums

Filebase computes a SHA256 over every object you upload to an object-storage bucket and returns it on every GetObject and HeadObject response. You can use it to verify a downloaded file matches the bytes on the server, or to compare two objects without downloading either of them.

What you get back

Two response headers, set on both GET and HEAD:

x-amz-checksum-sha256: n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=
x-amz-checksum-type: FULL_OBJECT
  • x-amz-checksum-sha256 is the base64 encoding of the 32-byte SHA256 digest — the same hash you'd get from running sha256sum on the file's original bytes.
  • x-amz-checksum-type: FULL_OBJECT confirms the hash covers the whole object as a single stream. For multipart uploads this matters — see Multipart objects below.

Reading the checksum

AWS CLI

aws --endpoint https://s3.filebase.io s3api head-object \
--bucket my-bucket \
--key path/to/object.bin \
--checksum-mode ENABLED
{
"ContentLength": 5242880,
"ContentType": "application/octet-stream",
"ETag": "\"7c4a8d09ca3762af61e59520943dc26494f8941b\"",
"ChecksumSHA256": "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=",
"ChecksumType": "FULL_OBJECT"
}

Pass --checksum-mode ENABLED so the CLI parses the checksum headers into the structured output. Filebase returns the headers either way, but the CLI hides them from the JSON output unless this flag is set.

AWS SDK for JavaScript v3

AWS SDK for JavaScript v3
import { S3Client, HeadObjectCommand } from '@aws-sdk/client-s3';

const s3 = new S3Client({
endpoint: 'https://s3.filebase.io',
region: 'us-east-1',
});

const out = await s3.send(
new HeadObjectCommand({
Bucket: 'my-bucket',
Key: 'path/to/object.bin',
ChecksumMode: 'ENABLED',
}),
);

console.log(out.ChecksumSHA256); // "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg="
console.log(out.ChecksumType); // "FULL_OBJECT"

AWS SDK for Python (boto3)

AWS SDK for Python (boto3)
import boto3

s3 = boto3.client('s3', endpoint_url='https://s3.filebase.io')

resp = s3.head_object(
Bucket='my-bucket',
Key='path/to/object.bin',
ChecksumMode='ENABLED',
)

print(resp['ChecksumSHA256']) # 'n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg='
print(resp['ChecksumType']) # 'FULL_OBJECT'

AWS SDK for Go v2

AWS SDK for Go v2
out, err := s3Client.HeadObject(ctx, &s3.HeadObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("path/to/object.bin"),
ChecksumMode: types.ChecksumModeEnabled,
})

fmt.Println(aws.ToString(out.ChecksumSHA256)) // base64 SHA256
fmt.Println(string(out.ChecksumType)) // "FULL_OBJECT"

curl

The simplest way is to issue a GET against a pre-signed URL and dump the response headers:

url=$(aws --endpoint https://s3.filebase.io s3 presign s3://my-bucket/path/to/object.bin)
curl -sD - -o /dev/null "$url" | grep -i checksum
x-amz-checksum-sha256: n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=
x-amz-checksum-type: FULL_OBJECT

Verifying a downloaded file

The header is the base64 encoding of the raw SHA256. Compare it against a locally-computed hash of the same bytes:

# Hash from Filebase:
expected=$(aws --endpoint https://s3.filebase.io s3api head-object \
--bucket my-bucket --key path/to/object.bin --checksum-mode ENABLED \
--query ChecksumSHA256 --output text)

# Hash of the local copy:
local=$(openssl dgst -binary -sha256 ./object.bin | base64)

[ "$expected" = "$local" ] && echo "match" || echo "mismatch"

If your platform doesn't have openssl, the same value comes from sha256sum:

local=$(sha256sum ./object.bin | awk '{print $1}' | xxd -r -p | base64)

Multipart objects

Objects uploaded via multipart have an ETag of the form <md5-of-md5s>-<part-count> — AWS's standard composite shape. Some SDKs interpret a composite ETag as a hint that the checksum is also composite (COMPOSITE: a hash of part hashes, not of the full object), and they verify accordingly. That would fail against Filebase.

To prevent that, Filebase always sets x-amz-checksum-type: FULL_OBJECT. The SHA256 is computed over the reassembled object's bytes during CompleteMultipartUpload, not as a hash of part hashes. The same value you'd get from sha256sum on the locally-reconstructed file matches what Filebase returns, for both single-part and multipart objects.

See Multipart upload for the full multipart walkthrough.

IPFS buckets

The x-amz-checksum-sha256 header is not returned for objects in IPFS-backed buckets. IPFS objects are identified by their CID (a multihash of the UnixFS DAG encoding), which is not equivalent to a SHA256 of the original bytes — splitting, chunking, and protobuf framing inside UnixFS mean the CID does not match sha256sum file.

For IPFS objects, the CID is returned in the x-amz-meta-cid header on every GET and HEAD response, and is the right value to use for content addressing. See the IPFS overview for the full model.

What's not supported

  • Other checksum algorithms. AWS S3 supports CRC32, CRC32C, SHA1, and SHA256. Filebase computes and returns SHA256 only — the other three headers (x-amz-checksum-crc32, x-amz-checksum-crc32c, x-amz-checksum-sha1) are never set.
  • Client-supplied checksums on upload. AWS lets you send x-amz-checksum-sha256 on a PutObject request to have S3 verify the body matches before persisting. Filebase accepts the header for compatibility but does not verify against it — Filebase always computes its own SHA256 from the bytes it receives. If you need an end-to-end integrity check, compare your locally-computed hash against the header on a subsequent HeadObject.
  • ChecksumMode: ENABLED as a required opt-in. AWS only returns checksum headers when the client opts in. Filebase returns them unconditionally — sending ChecksumMode: ENABLED is harmless and recommended (some SDKs only surface the values in their structured response when you do), but it's not required to make the header appear on the wire.

What's next