This page covers common failure scenarios you may encounter during deployment, authentication, and tool operation. Each section describes the symptoms and the most likely causes. For a full set of verification steps, see Verify.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/xxyoudeadpunkxx/cloudflare-r2-remote-mcp-worker/llms.txt
Use this file to discover all available pages before exploring further.
/healthz fails or returns ok: false
/healthz fails or returns ok: false
/healthz endpoint returns ok: false or an HTTP 503 when the Worker cannot reach the bound R2 bucket.Possible causes:- The
R2_BUCKETbinding is missing fromwrangler.jsonc. Confirm that the[[r2_buckets]]stanza is present and thatbinding = "R2_BUCKET". - The
bucket_namevalue inwrangler.jsoncis wrong or the bucket does not exist in your Cloudflare account. Create the bucket first withwrangler r2 bucket create <name>before deploying. - Your
wrangler.jsonchas multiple environments andwrangler deployis targeting the wrong one. Pass--env <name>explicitly to select the correct environment. - The Worker was deployed before the R2 bucket was created. Re-deploy after creating the bucket.
OAuth fails / 401 errors
OAuth fails / 401 errors
401 Unauthorized response or the OAuth flow fails to complete.Possible causes:AUTH_MODEis not set to"github"inwrangler.jsoncvars. Without this value, the Worker bypasses OAuth entirely and will reject requests that expect a token.- The
OAUTH_KVbinding is missing fromwrangler.jsoncor the KV namespace ID is wrong. The OAuth provider uses this namespace to store session state. GITHUB_CLIENT_IDorGITHUB_CLIENT_SECRETis missing or incorrect. Confirm both are set as Worker secrets withwrangler secret put.COOKIE_ENCRYPTION_KEYis not set as a Worker secret. This key is required for encrypting OAuth session cookies.- The GitHub OAuth App’s Authorization callback URL does not exactly match
https://<worker-url>/callback. Even a trailing slash mismatch will cause OAuth to fail. Update the callback URL in the GitHub OAuth App settings to match your deployed Worker URL.
Login succeeds but access denied (403)
Login succeeds but access denied (403)
403 Forbidden response.Possible causes:- The authenticated GitHub login is not listed in
ALLOWED_GITHUB_LOGINS. Add the login to the comma-separated list inwrangler.jsoncvars. ALLOWED_GITHUB_LOGINSis empty or the variable is not set. At least one login must be listed for any user to gain access.- The login appears to have different casing than what is stored. The Worker performs case-insensitive comparison automatically, so casing alone should not cause this error — double-check the exact login string in both places.
No tools visible in MCP client
No tools visible in MCP client
tools/list returns an empty array, or no tools appear in the client’s action/tool panel.Possible causes:- The client is connected to the wrong URL. Verify the endpoint is
/mcpand not/healthzor/. - The tool or action definitions have not been refreshed after the Worker was updated. Use the client’s refresh or reload option to re-fetch the tool list from the server.
- The Worker deployment failed silently. Check the Cloudflare dashboard Workers & Pages logs or review the output of
wrangler deployfor errors. - The client does not support streamable HTTP remote MCP. Confirm that your client version supports the MCP streamable HTTP transport before connecting to a remote Worker.
r2_object_get returns unsupported_content_type error
r2_object_get returns unsupported_content_type error
r2_object_get tool returns an error indicating the content type is not supported.Possible causes:- The object’s
Content-Typeis not text-like.r2_object_getreturns inline text only for types matchingtext/*,application/json,application/xml, and similar text formats. Binary formats such as images, videos, archives, and compiled files are not eligible for inline text delivery. - Use
r2_download_base64instead ofr2_object_getfor binary objects. The base64 tool has no content-type restriction.
payload_too_large errors
payload_too_large errors
- A text object exceeds
MAX_INLINE_TEXT_BYTES(default262144bytes, 256 KiB). The Worker will not return inline text content above this limit. - A binary object exceeds
MAX_TRANSFER_BYTES(default1048576bytes, 1 MiB). The Worker will not transfer binary content above this limit. - For objects larger than these thresholds, use presigned URLs (
r2_presign_getorr2_presign_put) so the client downloads or uploads directly from R2. Presign tools must be enabled withENABLE_PRESIGN_TOOLS=true.
Presign tools not appearing
Presign tools not appearing
r2_presign_get and r2_presign_put tools are not visible in tools/list.Possible causes:ENABLE_PRESIGN_TOOLS=trueis not set in thevarssection ofwrangler.jsonc. Add it and re-deploy.R2_ACCESS_KEY_IDandR2_SECRET_ACCESS_KEYare not set as Worker secrets. These S3-compatible credentials are required to generate presigned URLs. Create them in the Cloudflare dashboard under R2 → Manage API tokens and set them withwrangler secret put.R2_BUCKET_NAMEis not set inwrangler.jsoncvars. The presign implementation requires the bucket name as a string variable in addition to the R2 binding.
Account/admin tools not appearing
Account/admin tools not appearing
r2_account_list_buckets are not visible in tools/list.Possible causes:ENABLE_ACCOUNT_TOOLS=trueis not set in thevarssection ofwrangler.jsonc. Add it and re-deploy.CLOUDFLARE_API_TOKENis not set as a Worker secret. This token must have R2 read permissions. Set it withwrangler secret put CLOUDFLARE_API_TOKEN.CLOUDFLARE_ACCOUNT_IDis not set inwrangler.jsoncvars. The account tools use this value to scope API requests to the correct Cloudflare account.
etag_conflict (409) on put
etag_conflict (409) on put
r2_object_put call returns a 409 Conflict with an etag_conflict error code.Possible causes:- The
expectedEtagparameter was provided but the current object’s ETag does not match. This means the object was modified between the time you fetched its metadata and the time you attempted the write. - Re-fetch the object metadata using
r2_object_headto get the current ETag, then retry the put with the updated value or omitexpectedEtagif conditional writes are not required.
object_already_exists (409) on put_if_absent
object_already_exists (409) on put_if_absent
r2_object_put_if_absent call returns a 409 Conflict with an object_already_exists error code.Possible causes:- An object already exists at the given key. The
r2_object_put_if_absenttool performs a conditional write that fails if the key is already occupied — it is designed to prevent accidental overwrites. - If overwriting the existing object is acceptable, use
r2_object_putinstead. - If you want to write only if the object is absent and also obtain the current object’s content when it already exists, call
r2_object_getfirst, then decide whether to write based on the result.
destination_exists (409) on copy or move
destination_exists (409) on copy or move
r2_object_copy or r2_object_move call returns a 409 Conflict with a destination_exists error code.Possible causes:- An object already exists at the destination key and
allowOverwritewas not set totruein the tool call. - Set
allowOverwrite: truein the tool arguments to permit the overwrite, or choose a different destination key.
no_op_rename (400) on rename
no_op_rename (400) on rename
r2_object_rename call returns a 400 Bad Request with a no_op_rename error code.Possible causes:- The new name provided is identical to the current object name. The Worker rejects renames that would result in no change.
- Verify that the
newNameargument differs from the current basename of the object key.
invalid_path (400) on any tool
invalid_path (400) on any tool
400 Bad Request with an invalid_path error code.Possible causes:- The key or path argument is empty, an absolute path (starts with
/), or contains a Windows-style drive letter (e.g.C:\). - The path contains
.or..segments, or includes null bytes. - For
r2_object_rename, thenewNameargument is empty, contains a path separator, or is otherwise not a valid basename. - Provide a relative path with no special segments. Paths must be non-empty strings using only forward slashes as separators.
tools/list via MCP Inspector, and the SDK smoke test — see Verify the R2 MCP Worker Deployment is Healthy.