Skip to content

Upsert option for signed bucket file URL errors with HTTP 409 "The resource already exists" message #1254

@rwspeight

Description

@rwspeight

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

Attempting to upsert over a pre-existing storage bucket file using client.storage.from_(bucket).upload_to_signed_url(...) with upsert="true" FileOption results with error {'statusCode': 409, 'error': Duplicate, 'message': The resource already exists}.

To Reproduce

Run the following code.

from supabase.client import create_client
from storage3.types import FileOptions

url="..."
key="..."
client = create_client(url, key)

bucket='bucket01'
file="file01.txt"

print("\n========")
print("Creating signed URL...")
response = client.storage.from_(bucket).create_signed_upload_url(file)

path=response["path"]
token=response["token"]
print(f"path={path}, token={token}")

try:
    file_options = FileOptions(upsert="true")
    # Extension header not assigned true by above constructor
    file_options["x-upsert"] = file_options["upsert"]

    print("First upload...")
    bytes1 = b'Foo'
    client.storage.from_(bucket).upload_to_signed_url(path, token, bytes1, file_options=file_options)
    
    print("Second upload...")
    bytes2 = b'Bar'
    client.storage.from_(bucket).upload_to_signed_url(path, token, bytes2, file_options=file_options)
except Exception as e:
    print(e)
finally:
    print("========\n")

Results in following output

    ========
    Creating signed URL...
    path=file01.txt, token=eyJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJidWNrZXQwMS9maWxlMDEudHh0IiwidXBzZXJ0IjpmYWxzZSwiaWF0IjoxNzU5OTc3MDEzLCJleHAiOjE3NTk5NzcwNzN9.axKo6ogNonUPtOEQ4cPP9aXsRmGIf5rUALkSLqXj_7s
    First upload...
    Second upload...
    {'statusCode': 409, 'error': Duplicate, 'message': The resource already exists}
    ========

Expected behavior

The second call to client.storage.from_(bucket).upload_to_signed_url() does not return an error and pre-existing file content is updated.

Screenshots

N/A

System information

  • Supabase Python client v2.22.0
  • Reproduced on both local dev container public.ecr.aws/supabase/storage-api:v1.27.4 as well current production version (as of 10/08/2025).

Additional context

The Python client (and perhaps other clients) seem to expose a feature that is not supported by the backing Supabase Storage API. Looking at the OpenAPI spec and the endpoint implementation does not seem to explicitly look for an "upsert" flag. There is some code in the implementation that pulls an upsert flag from the JWT, but tracing that down ended at what looks like key/values pulled from the platform somewhere and not a per-call value.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions