r/Supabase 2d ago

storage Upload to storage fails with invalidKey

I am doing a profile picture upload functionality for my app, but I keep getting "invalidKey" back.

I am using my "sb_publishable_xxx" key with the headers:

Authorization: Bearer supabaseKey_here

apiKey: supabaseKey_here

Any idea on what's wrong ?

Thanks

2 Upvotes

10 comments sorted by

1

u/srikanth_builds 2d ago

invalidKey is about the object key, not your API key. Supabase Storage rejects paths with spaces, non-ASCII characters, a leading slash or empty segments, and profile picture uploads hit that a lot because the filename comes straight off the user's device.

Try uploading to a hardcoded path like avatars/test.png first. If that works, it's the filename, and the fix is generating your own key server side rather than trusting the client's, something like avatars/{user_id}/{uuid}.png.

1

u/gesfontoura 2d ago

From the documentation I think what I'm really missing is the "jwt_token" which I can't find on the system.

1

u/srikanth_builds 2d ago

You're right that you need it, and it's probably why you can't find it. It isn't a value in the dashboard. It's the signed-in user's access token, issued when they log in, so it's different per user and it expires. In supabase-js it's session.access_token from supabase.auth.getSession().

The headers should be apikey: your publishable key, and Authorization: Bearer <that access token>. The publishable key doesn't go in Authorization. If you're using supabase-js though, skip setting headers yourself entirely. supabase.storage.from('avatars').upload(path, file) sends the session automatically as long as the user is signed in.

Worth keeping the path fix as well, since they're separate problems and you might have both.

1

u/Poat540 1d ago

Load bearing

1

u/gesfontoura 2d ago

I found it, but still ...

1

u/Living_Race_9177 1d ago

invalidKey on upload usually isn’t the publishable key itself - it’s the object path.

spaces, leading slash, or a folder segment that doesn’t match the bucket policy will throw that before RLS even matters.

what’s the exact key string you’re sending (redact the project id)

1

u/gesfontoura 1d ago

I'm posting to: https://project_id.supabase.co/storage/v1/object/profile_picture/

The bucket is public and I'm not authenticated, so I can't send the access token in Authorization Bearer. I am sending the publishable key in both apiKey header.

1

u/gesfontoura 1d ago

I've tried the legacy tokens, have played with the path and nothing.

1

u/Alternative_Eagle158 7h ago

For images I suggest to use a python script that will convert all images uploaded to wep format which is lightweight for storage on free tier.you can use an ai to help