aws s3 cp: Copy Files to and from S3
aws s3 cp copies files between the local filesystem and S3, or between two S3 locations, using the high-level AWS CLI s3 commands.
aws s3 cp is the default way to push a build artifact to a bucket. It supports recursive directory copies and streaming to and from stdin, and it handles multipart uploads automatically for large files.
What it does
aws s3 cp copies a single object or, with --recursive, a directory tree, between local paths and s3:// URLs. It automatically uses multipart uploads for large files. Use - as source or destination to stream via stdin/stdout.
Common usage
aws s3 cp ./build.tar.gz s3://my-bucket/artifacts/build-${GITHUB_SHA}.tar.gz
aws s3 cp ./dist s3://my-bucket/site --recursive
# stream a tar straight to S3
tar czf - ./out | aws s3 cp - s3://my-bucket/artifacts/out.tar.gzOptions
| Flag | What it does |
|---|---|
| --recursive | Copy a directory tree |
| --sse aws:kms | Server-side encryption (SSE-S3 or SSE-KMS) |
| --content-type <type> | Set the object Content-Type |
| --cache-control <value> | Set the Cache-Control header |
| --only-show-errors | Suppress the per-file progress output in logs |
| --endpoint-url <url> | Target an S3-compatible endpoint |
In CI
Use --only-show-errors to keep pipeline logs clean. Authenticate with an OIDC-assumed IAM role (AWS_ROLE_ARN + web identity token) instead of static keys so nothing long-lived sits in secrets. For large artifacts the CLI multiparts automatically; tune aws configure set s3.max_concurrent_requests for throughput.
Common errors in CI
"An error occurred (AccessDenied) when calling the PutObject operation: Access Denied" means the role lacks s3:PutObject on the prefix. "(NoSuchBucket) ... The specified bucket does not exist" is a wrong bucket or region. "(InvalidAccessKeyId) The AWS Access Key Id you provided does not exist" is a wrong key. "(SignatureDoesNotMatch)" is a wrong secret or clock skew. "(RequestTimeTooSkewed)" means the runner clock drifted; sync NTP.