An SFTP server for Cloudflare R2, with free egress on downloads
R2 can't accept SFTP itself. CloudFile gives you an SFTP, FTPS and FTP server that writes into your R2 bucket, so partners keep their clients and your Workers read the files from the same bucket.
Cloudflare R2 with CloudFile, at a glance.
| Endpoint | https://<account-id>.r2.cloudflarestorage.com, or <account-id>.eu.r2.cloudflarestorage.com for an EU-jurisdiction bucket |
|---|---|
| URL style | Path-style, region auto |
| Credentials | Access Key ID and Secret Access Key from an R2 API token with Object Read & Write on one bucket. Not the cfat_ token value. |
| Location | Automatic, a best-effort location hint, or a jurisdiction such as the EU that guarantees where data is stored |
| Pricing model | $0.015 per GB-month for Standard storage, Class A operations $4.50 and Class B $0.36 per million. No egress fees. 10 GB-month free. |
Cloudflare R2 prices are from their public website as of October 2026, excluding taxes. Your bucket is billed by Cloudflare R2, not by us, and doesn't count toward your plan's storage.
Why pair SFTP with Cloudflare R2.
Downloads don't cost egress
Partners downloading files, and your code fetching webhook download links, pull data out of R2 without a per-GB transfer charge.
EU data residency you can prove
Create the bucket in the EU jurisdiction and objects are stored inside the EU. Jurisdictions are guaranteed; location hints are not.
Process files in a Worker
A webhook hits your Worker with the file path, and the Worker reads the object from the same bucket through an R2 binding. No VM in between.
A token scoped to one bucket
R2 API tokens can be limited to specific buckets and to object read and write, so CloudFile's key can't touch anything else in the account.
How it works, in three steps.
- Step 1
Create a bucket and an API token
Pick a jurisdiction if contracts require it. Create an Account API token with Object Read & Write on that bucket only, and copy its Access Key ID and Secret.
R2 token Object Read & Write acme-sftp - Step 2
Connect it in CloudFile
Storage → Add bucket → Cloudflare R2. Enter the Account ID and we build the endpoint. Add .eu for an EU bucket.
https://<account-id>.eu.r2.cloudflarestorage.com ✓ - Step 3
Partners upload, R2 receives
Files land under one prefix per user. Your Worker gets a signed webhook and reads the object from R2.
acme → r2://acme-sftp/acme/orders/2026-10.csv
Every click and field is in the Cloudflare R2 setup guide.
What your partners see, and where it lands in Cloudflare R2.
$ sftp -P 22000 [email protected]
sftp> put invoice-2026-10.pdf
sftp> ls
invoice-2026-10.pdfYour Cloudflare R2 bucket<bucket>/<folder>/acme/invoice-2026-10.pdf
<bucket>/<folder>/_shared/inbox/…Any SFTP, FTPS or FTP client: FileZilla, WinSCP, Cyberduck, the sftp command or their own system. WebDAV too, if you turn it on.
Their own home folder as /, and nothing else. They never see the bucket name, other users' folders or your keys.
A password, an SSH key or both, with the permissions you pick: full access, read only or upload only.
Shared folders at /shared/<name> when several users need the same files. They live under _shared/<name>/ in your Cloudflare R2 bucket.
Get these right in Cloudflare R2.
Keep the bucket's Public Development URL off and don't attach a custom domain: either makes every file readable by anyone who guesses a path.
A bucket's jurisdiction can't be changed after it's created, and a jurisdiction bucket needs the jurisdiction in the endpoint.
Paste the Access Key ID and Secret Access Key shown with the token, not the cfat_ token value.
Questions about SFTP on Cloudflare R2.
Can R2 run SFTP on its own?
No. R2 speaks the S3 API and the Workers API. CloudFile adds an SFTP, FTPS, FTP and WebDAV server in front of your bucket.
Is data really kept in the EU?
If you create the bucket in the EU jurisdiction, Cloudflare guarantees the objects are stored there. A location hint like Western Europe is best-effort only. CloudFile's SFTP servers run in Germany.
Why does the test fail with 'bucket does not exist'?
Usually the bucket is in a jurisdiction and the endpoint is missing it. Use https://<account-id>.eu.r2.cloudflarestorage.com for EU buckets.
Can I serve the uploaded files publicly?
We recommend keeping the bucket private. CloudFile hands out presigned links that expire after an hour; if you need public files, put them in a separate bucket.
More in the docs: Cloudflare R2 setup · Your own bucket · Webhooks