Nodes/Duanyll Nodepack/Upload Image to S3
ComfyUI Node

Upload Image to S3

Push Your Output to S3 and Get Back a Public URL

By Duanyll·Created about a year ago·Updated 4 months ago· 2
Upload Image to S3
  • s3_client
  • image
  • public_url
keycomfyui/output/image.png
formatpng
quality90
webp_losslessfalse

Sometimes "save to output/" isn't the end of the pipeline. If you're building a bot that posts results, a web app that needs a URL, or any automated flow where the next step wants a hosted image, UploadImageToS3 is the node that takes your IMAGE tensor, writes it to an S3-compatible bucket, and hands back the public URL.

It pairs with the pack's CreateS3Client node, which holds the connection config - so the workflow reads: client config → upload → URL out. The defaults target Backblaze B2 (a cheap, S3-compatible object store popular with indie builders), but any S3-compatible endpoint works.

How it works

The neat bit: it doesn't use boto3. The node generates AWS Signature V4 headers itself (HMAC-signed, no SDK dependency) and does a plain requests.put to your endpoint. That keeps the pack's dependency list light and means it works against any S3-compatible service that speaks SigV4 - B2, MinIO, AWS, Cloudflare R2-style setups, whatever.

The flow: the image tensor gets converted to PIL, encoded to your chosen format (PNG, JPEG, or WebP), signed, and PUT to endpoint/bucket/key. It even rewrites the key's extension to match the format you picked, so image.png + jpeg becomes image.jpeg. The public_url output is built from the public_url_base you configured, joined with the final key.

Inputs that matter

  • s3_client - the S3_CLIENT object from CreateS3Client (endpoint, bucket, region, keys, public URL base). No client, no upload.
  • image - the IMAGE tensor to ship.
  • key - the object path in the bucket (default comfyui/output/image.png).
  • format (png/jpeg/webp), quality (1–100, default 90), webp_lossless - encoding knobs. JPEG flattens alpha; if you need transparency, use PNG or WebP.

Output is a public_url string.

Installing it

Part of Duanyll Nodepack:

cd ComfyUI/custom_nodes
git clone https://github.com/Duanyll/duanyll_nodepack

or via ComfyUI Manager, then restart. No extra model downloads; it just needs outbound HTTPS.

Where people get burned

  • The URL isn't actually public. public_url_base is your claim about where the object is reachable - the node concatenates it, it doesn't verify. If the bucket isn't public-read or the base doesn't match the bucket/endpoint, the URL 404s. Check bucket permissions before blaming the node.
  • Keys are credentials. The secret key field is marked as a password input and never leaves your machine (requests just signs with it), but if you're sharing a workflow JSON, strip the client node's key fields - that's a leak waiting to happen.
  • Wrong region breaks the signature. SigV4 signs with the region string; if it doesn't match the bucket's actual region, you'll get an auth error from the storage side, not the node. The B2 defaults are correct for B2's us-west-004 - change region and endpoint together.
  • The upload error message is the storage's, passed through. A failed PUT prints the S3 response body to the console, which usually names the real cause (auth, bucket missing, region).

It's the right tool when you need hosted output, and the wrong tool if you just want a local file - for that, use the built-in SaveImage.

Categoryduanyll/web

Inputs (6)

NameTypeDefaultDescription
s3_clientS3_CLIENT
imageIMAGE
keySTRINGcomfyui/output/image.png
formatoptCOMBOpng3 options: png, jpeg, webp
qualityoptINT901–100
webp_losslessoptBOOLEANfalse

Outputs (1)

NameTypeDescription
public_urlSTRING