S3 Upload Image
Push workflow output straight to a bucket, no local save needed
- images
- s3_url
- path
- image
S3 Upload Image is the workhorse of the S3 Connector pack: it takes whatever IMAGE tensor your workflow produced and uploads it to an S3 bucket as a PNG. You'd reach for this when ComfyUI's normal output folder isn't where the images need to end up - a headless rendering box that dumps results into object storage, a pipeline that hands outputs to another service, or you just want everything in the same bucket you already use. Crucially, it does not write a local file. Whatever goes up only lives in S3 (plus memory), so this isn't a drop-in replacement for SaveImage - keep a SaveImage node in the graph if you want a local copy too.
How it works
Under the hood it's boto3.upload_fileobj. The node converts the tensor to a uint8 RGB numpy array, makes a PIL image, encodes it as PNG bytes in memory, and uploads with ContentType: image/png. The S3 key is assembled from your configured S3_PREFIX plus the folder_path and file_name you type in. It then builds the returned URL itself rather than asking S3 for one - more on that gotcha below.
The three inputs that matter are exactly what you'd expect:
images(IMAGE) - the tensor from your sampler/VAE decode.folder_path(STRING) - subfolder in the bucket, e.g.portraits/2024. Leave blank to upload at the prefix root.file_name(STRING) - filename; if it has no extension it gets.pngappended. The node refuses to run with an empty one.
Outputs are s3_url (the URL it constructed), path (the actual S3 key), and image (the same tensor passed through, so you can chain it into SaveImage or other nodes). If you feed it a batch, it uploads each frame as name_0.png, name_1.png… and only returns the last one's URL and key.
Configuring the bucket
Credentials come from a .env file that lives inside the node's own folder (custom_nodes/comfyui-s3-connector/.env), not your ComfyUI root - a classic place to trip up:
cd ComfyUI/custom_nodes
git clone https://github.com/haranesh/comfyui-s3-connector
cd comfyui-s3-connector
pip install -r requirements.txt
cp .env.example .env
Then fill in S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, and S3_BUCKET_NAME (all required - the node raises if the bucket name is missing). S3_REGION defaults to us-east-1, S3_ENDPOINT_URL is empty for real AWS and set to something like http://localhost:9000 for MinIO, and S3_PREFIX prepends to every key. Restart ComfyUI after setting it up. ComfyUI Manager also works - search "S3 Connector". Dependencies are just boto3, python-dotenv, and Pillow; no model files.
Where people get burned
The constructed s3_url is only actually loadable if the bucket is public (or you have your own signed-URL layer). The node never checks - it just formats https://{bucket}.s3.{region}.amazonaws.com/{key} (or {endpoint}/{bucket}/{key} for MinIO-style setups). If the URL 404s in a browser, the upload worked but your bucket isn't publicly readable. Also: everything becomes RGB PNG, so any alpha channel in the source image is silently dropped on upload. Fine for most outputs, a trap if you're shipping transparent PNGs around. This pack also has no progress reporting - you stare at the console line [S3 Connector] Uploaded: ... when it finishes. There are fancier cloud-save packs with progress bars and multiple providers, but if you just need S3 (or anything S3-compatible), this is the simplest thing that works.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| folder_path | STRING | — | |
| file_name | STRING | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| s3_url | STRING | — |
| path | STRING | — |
| image | IMAGE | — |