Nodes/S3 Serverless-Inline Storage Utils/S3 Image Upload (Inline Credentials)
ComfyUI Node

S3 Image Upload (Inline Credentials)

Upload your ComfyUI output straight to S3 — keys go right in the node

By udayjain26·Created about a year ago·Updated 6 months ago· 1
S3 Image Upload (Inline Credentials)
  • images
  • s3_urls
  • upload_status
  • uploaded_count
filename_prefixcomfy_image
bucket_name
access_key_id
secret_access_key
regionus-east-1
endpoint_url
folder_pathuploads

S3 Image Upload is the node that gets your finished image off the local machine and into a bucket without a single environment variable. You type your access key, your secret, and your bucket name into the node's own fields, hit run, and the image is in S3 by the time the graph finishes. No ~/.aws file, no IAM role to hunt for, no CLI setup - if the keys work in the AWS console, they work here.

That "inline credentials" design is the whole point of this pack, and it's genuinely aimed at a specific pain: serverless and ephemeral ComfyUI deployments (Modal, RunPod serverless, a Docker container that gets recycled) where you can't reliably bake credentials into the environment. A pack that reads AWS_ACCESS_KEY_ID from env vars is a non-starter there; this one carries everything in the node.

How it works

The node takes your IMAGE tensor, converts it to RGB, and saves it as a WebP file (quality 100, lossless off) to a temp file. Then it builds a boto3 client with the credentials you provided - no default credential chain involved - and uploads. Filenames are dead simple: filename_prefix.webp, or prefix_1.webp, prefix_2.webp if you feed it a batch. The extension is always .webp, no matter what your prefix says. It returns the public URL for each upload.

It's smart about S3-compatible services in a way that saves you real pain. For plain AWS it constructs https://<bucket>.s3.amazonaws.com/<key>. For Supabase it switches to path-style addressing and builds an /object/public/<bucket>/<key> URL, because that's what Supabase's S3 gateway actually serves. Anything else - Cloudflare R2, MinIO, DigitalOcean Spaces - gets a path-style <endpoint>/<bucket>/<key> URL.

The inputs that matter

  • images - the IMAGE output from your VAE decode (or anything downstream of it).
  • bucket_name, access_key_id, secret_access_key, region - paste them in. Region defaults to us-east-1; change it to your bucket's real region.
  • endpoint_url - leave empty for AWS. For Supabase use https://<your-project>.supabase.co/storage/v1/s3, and for R2/MinIO/Spaces use their endpoint.
  • folder_path (default uploads) - the "folder" prefix inside the bucket.

Outputs are s3_urls (a list), upload_status, and uploaded_count. The status string and count are your tripwire: on any failure you get uploaded_count of 0 and a status that says what went wrong, instead of a thrown error killing your whole run.

Install

ComfyUI Manager is the easy path - search for s3_serverless_inline_storage_utils and install. Or clone it yourself:

cd ComfyUI/custom_nodes
git clone https://github.com/udayjain26/s3_serverless_inline_storage_utils

Restart ComfyUI and you'll find the nodes under S3 Serverless Storage. No model downloads - this pack is pure code. Manager installs the pip deps (boto3, botocore, pillow, requests) automatically; if you cloned by hand and imports fail, run pip install boto3 botocore pillow requests yourself.

Troubleshooting

The failure messages come back through upload_status, so check that first. "Bucket does not exist" or "Access denied" mean exactly what they say - check the bucket name and that your IAM user has s3:PutObject on it. Signed-URL note: the URL this node builds is not itself signed, so for a private bucket the returned URL won't open in a browser - that's expected; it's for other services that can reach the bucket. Two timeouts are baked in at 60 seconds each, with adaptive retries, so transient network blips usually sort themselves out.

One security warning worth taking seriously: a ComfyUI workflow you save as a PNG carries the whole node graph embedded in the image. That means your access key and secret travel inside any PNG you share that contains this node. Clear the credential fields before you drag your workflow into a Discord post - the README says it, and it's the one habit you actually need.

If your uploads keep failing only on big batches, it's usually a bucket policy or a CORS thing on the storage side, not this node. Verify with a single image first.

CategoryS3 Serverless Storage

Inputs (8)

NameTypeDefaultDescription
imagesIMAGEImages to upload to S3
filename_prefixSTRINGcomfy_imagePrefix for uploaded filenames
bucket_nameSTRINGS3 bucket name
access_key_idSTRINGAWS Access Key ID
secret_access_keySTRINGAWS Secret Access Key
regionSTRINGus-east-1AWS region
endpoint_urloptSTRINGCustom S3 endpoint URL (for S3-compatible services like Supabase)
folder_pathoptSTRINGuploadsFolder path within bucket

Outputs (3)

NameTypeDescription
s3_urlsSTRING
upload_statusSTRING
uploaded_countINT