aws s3api put-object: Low-Level S3 Uploads
aws s3api put-object uploads one object with the low-level API, letting you set metadata, content type, ACL, and encryption explicitly.
When you need precise control (custom metadata, a specific Content-Type, SSE-KMS, or a conditional put) the low-level put-object beats the high-level cp. It reads the body from a file with --body.
What it does
aws s3api put-object calls the S3 PutObject API for a single object. --body names the local file to upload; other flags set Content-Type, Cache-Control, user metadata, ACL, and server-side encryption. Unlike s3 cp, it does not multipart large files, so it suits small objects.
Common usage
aws s3api put-object --bucket my-bucket --key config.json \
--body ./config.json --content-type application/json
# with KMS encryption and custom metadata
aws s3api put-object --bucket my-bucket --key data.bin \
--body ./data.bin --sse aws:kms --metadata build=${GITHUB_SHA}Options
| Flag | What it does |
|---|---|
| --bucket <name> / --key <key> | Destination bucket and object key |
| --body <file> | Local file to upload as the object body |
| --content-type <type> | Set the Content-Type header |
| --metadata <k=v,...> | User-defined metadata |
| --sse aws:kms | Server-side encryption (SSE-S3 or SSE-KMS) |
| --acl <canned-acl> | Canned ACL such as private or public-read |
In CI
Reach for put-object when you must set metadata or a precise Content-Type that s3 cp would guess wrong. For large files or many files, use aws s3 cp/sync or s5cmd, which multipart and parallelize. With SSE-KMS the role also needs kms:GenerateDataKey on the key.
Common errors in CI
"(AccessDenied) when calling the PutObject operation" means missing s3:PutObject, or missing kms:GenerateDataKey when --sse aws:kms is set. "(NoSuchBucket)" is a wrong bucket or region. "(EntityTooLarge)" means the single-part put exceeds the 5 GiB limit; switch to aws s3 cp for multipart. "(SignatureDoesNotMatch)" or "(RequestTimeTooSkewed)" are wrong keys or a skewed runner clock.