> ## Documentation Index
>
> Fetch the complete documentation index at: https://lithi.ai/llms.txt
>
> Use this file to discover all available pages before exploring further.

---
title: Cloudflare R2
description: >-
  Use Cloudflare R2 through the measured subset stated on its conformance matrix. Covers signed
  URL scope and expiry, required headers, checksums and what is not supported.
route: /docs/compute/integrations/cloudflare-r2
page_id: docs-compute-integrations-cloudflare-r2
page_type: howTo
content_layer: guided documentation
surface_profile: guided_docs
audience: Engineers pointing Compute at R2 buckets with an existing S3-style client
voice: D
reader_question: Which parts of my S3-style client actually work against R2 here?
primary_action: Read the four compatibility levels
source_locale: en-US
source_status: APPROVED
source_version: docs-compute-integrations-cloudflare-r2-en-us-2026-09-05-v1
last_updated: '2026-09-05'
robots: index
claim_registry_pinned: true
claim_registry_resync: "npm run governed:tsx -- scripts/build-compute-public-claim-registry.ts --write"
---

## What this adapter states

Read these eleven facts off the adapter's descriptor and its published conformance matrix before you register anything.

| Fact | Where you read it |
| --- | --- |
| Provider product | Cloudflare R2 object storage |
| Tested upstream version | The matrix names the exact API version tested |
| Supported direction | Input, output, or both, as declared on the descriptor |
| Credential mode | A stored credential reference, never a literal secret |
| Input snapshot binding | A `version_id` and a `content_sha256` pinned before admission |
| Formats | The formats the workflow declares, listed on its descriptor |
| Output commit mode | Written once to a new partition, verified, then committed |
| Unsupported fields | Named explicitly in the matrix, not left out |
| Limits | Measured size, count and rate bounds in the matrix |
| Expiry | The signed authority's lifetime and who renews it |
| Compatibility level | One of the four named levels, with a matrix version |

## Plan against the measured subset only

R2 speaks an S3-style protocol, and this adapter documents the part of it that was measured. That part is the matrix, not the whole protocol.

Do not assume a field works because your client sets it against a different product. Compare your client's fields against the field coverage row, one at a time.

Anything named under unsupported behavior will refuse rather than silently ignore you. That is the outcome you want.

## Headers and checksums are part of the contract

The matrix states the exact headers the adapter sends and requires. Match them; a header your client adds by habit may not be covered.

Checksums are how a transfer is proven rather than assumed. Supply the checksum the matrix names, and check that the value you sent is the value recorded.

If a checksum mismatch appears, stop. A mismatch is a data-integrity signal, not a retry prompt.

## Signed URLs are bearer authority

A signed URL is temporary authority to perform one exact operation on one exact resource. Whoever holds it, holds that permission.

Two properties matter and are usually misremembered.

- It is not inherently single-use. Assume it can be presented more than once before it expires.
- It expires on its own clock, which is why a URL that worked an hour ago fails now.

So keep the lifetime as short as the transfer allows, and scope it to one operation and one object. A signed URL must never appear in a log, a support request or a receipt.

## Register a credential reference

Your request carries a `credential_ref` pointing at a secret your account already holds. The secret itself never travels in a request. Store it first, as described in [how to register a data source](/docs/compute/configure/sources).

Grant read on the input prefix and write on a separate output prefix. Never reuse one grant for both directions.

Keep your examples free of account identifiers and bucket ownership details. A support note needs the receipt reference, not your infrastructure.

## Test with a bounded transfer

Run the source family's `test` on one object, and the destination family's `test` on one small write.

The destination test must reach a committed state. Creating an object is not the same permission as finalizing one, and the difference only shows under real delivery.

## Confirm success

Both resources read back as `VERIFIED`, both tests pass, and the destination test reaches a committed write.

A real job's delivery then reaches `COMMITTED` and finally `CUSTOMER_ACKNOWLEDGED`. `WRITTEN_UNVERIFIED` is not done; it means bytes exist and nothing has confirmed them.

If a delivery fails, read its reason and next action together. `AUTHORITY_EXPIRED` means renew and retry, and never means the result was lost.

[Read the four compatibility levels](/docs/compute/integrations/compatibility-levels)
