S
Supabase•3mo ago
LittleCat

Corrupted File on upload

Hi! I am using supabase-js
"@supabase/supabase-js": "^2.50.0",
"@supabase/supabase-js": "^2.50.0",
I am facing an issue where every upload that I did contains this in the file header
------WebKitFormBoundaryq1P65x9Cx4VFT0SU
Content-Disposition: form-data; name="cacheControl"

3600
------WebKitFormBoundaryq1P65x9Cx4VFT0SU
Content-Disposition: form-data; name=""; filename="topsecret.txt"
Content-Type: application/octet-stream
------WebKitFormBoundaryq1P65x9Cx4VFT0SU
Content-Disposition: form-data; name="cacheControl"

3600
------WebKitFormBoundaryq1P65x9Cx4VFT0SU
Content-Disposition: form-data; name=""; filename="topsecret.txt"
Content-Type: application/octet-stream
When uploading via the dashboard, the file uploads fine. When uploading via the JS SDK, the header get inserted to every file happens. Here are my code snippets
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const selectedFiles = event.target.files;
if (selectedFiles && selectedFiles.length > 0) {
const file = event.target.files?.[0]
if(file != null){
supabase.storage.from("bucket-name").upload(`users/abc/testUpload/${file?.name}`, file, {
upsert: true,
contentType: "text/plain"
}).then(file => {
console.log(file.data)
})
}
}
};
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const selectedFiles = event.target.files;
if (selectedFiles && selectedFiles.length > 0) {
const file = event.target.files?.[0]
if(file != null){
supabase.storage.from("bucket-name").upload(`users/abc/testUpload/${file?.name}`, file, {
upsert: true,
contentType: "text/plain"
}).then(file => {
console.log(file.data)
})
}
}
};
I did have a browse through the issue tracker(https://github.com/supabase/supabase/issues/36929) and this seems related? Anyone facing the same issue?
GitHub
[Bug] Storage in sa-east-1: Successful PNG uploads are being served...
Bug report Hello, I&#39;m experiencing a critical bug with Supabase Storage in my project. Project Ref: gnmxihdaawlenwspsxum Region: sa-east-1 Problem: When I upload a valid PNG file (e.g., ~745KB)...
29 Replies
garyaustin
garyaustin•3mo ago
Is this React Native?
LittleCat
LittleCatOP•3mo ago
It's nextjs
garyaustin
garyaustin•3mo ago
Not enough info from that user's issue as they don't even say how they are uploading. No other reports I've seen. The storage UI does use the REST API, so seems something about your method. Is it one particular file? Does the corrupted file have a length?
LittleCat
LittleCatOP•3mo ago
It's every file that's uploaded via the SDK. I did a console log before uploading and the file looks fine. The length of the file is the same when I look via network inspector
garyaustin
garyaustin•3mo ago
I see this header when I upload...
No description
LittleCat
LittleCatOP•3mo ago
I will test it via the kotlin SDK and REST API. I might be able to replicate this issue
garyaustin
garyaustin•3mo ago
function handleFiles() {
const fileList = this.files;
const myFile = fileList[0]
user_id = user2.session.user.id
filename = user_id+'abxxxxxddxxxxxxxsdddxxxxssd9'
async function loadfile() {
const fileresult = await supabases[2]
.storage
.from('test6')
.upload(filename,myFile,{metadata:{'mydata':'123ddddd566'}})
}
function handleFiles() {
const fileList = this.files;
const myFile = fileList[0]
user_id = user2.session.user.id
filename = user_id+'abxxxxxddxxxxxxxsdddxxxxssd9'
async function loadfile() {
const fileresult = await supabases[2]
.storage
.from('test6')
.upload(filename,myFile,{metadata:{'mydata':'123ddddd566'}})
}
2.50.3 supabase-js
LittleCat
LittleCatOP•3mo ago
What happens when you download the file via the dashboard?
garyaustin
garyaustin•3mo ago
It is fine. There is no general issue with storage or there would be lots of reports. And if you can upload with UI then not likely your instance. You are using .name for an extension? Is the mimetype being set in your fileobject to .txt?
garyaustin
garyaustin•3mo ago
I'm not sure the contentType overrides what is in the blob or extension of the filename for a blob upload. This reads like it is not.
No description
garyaustin
garyaustin•3mo ago
What does the storage UI say the mime type is?
garyaustin
garyaustin•3mo ago
No description
LittleCat
LittleCatOP•3mo ago
I'm using txt as my extension. ${file.name} expands to testfile.txt The storage UI says the mime type is application/json
garyaustin
garyaustin•3mo ago
Oh sorry, just glanced. How are you getting the file into the blob object?
LittleCat
LittleCatOP•3mo ago
garyaustin
garyaustin•3mo ago
And what type is it? What is file.name when you log it out? Are you uploading from the browser in a browser client (versus a server component)? I don't use next.js, so may not make sense.
LittleCat
LittleCatOP•3mo ago
console.log shows testfile.txt. I am uploading via browser <input type="file" hidden id="browse" ref={fileInputRef} onChange={handleFileChange} multiple={false} />
inder
inder•3mo ago
When I upload txt file from dashboard, the mime type is text/plain. When uploading file, you can try setting mime type yourself mime type is also available on the File object. file.type
LittleCat
LittleCatOP•3mo ago
this is the content of the file when uploaded
No description
LittleCat
LittleCatOP•3mo ago
No description
inder
inder•3mo ago
Did you set mimetype when uploading?
No description
inder
inder•3mo ago
It says it defaults to text/plain but still
LittleCat
LittleCatOP•3mo ago
I shouldn't have to manually set the content type but I did it anyway
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const selectedFiles = event.target.files;
if (selectedFiles && selectedFiles.length > 0) {
const file = selectedFiles?.[0]
if(file != null){
supabase.storage.from("bucket-name").upload(`users/abc/testUpload/testile.txt`, file, {
upsert: true,
contentType: "text/plain"
}).then(file => {
console.log(file.data)
})
}

}
};
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const selectedFiles = event.target.files;
if (selectedFiles && selectedFiles.length > 0) {
const file = selectedFiles?.[0]
if(file != null){
supabase.storage.from("bucket-name").upload(`users/abc/testUpload/testile.txt`, file, {
upsert: true,
contentType: "text/plain"
}).then(file => {
console.log(file.data)
})
}

}
};
LittleCat
LittleCatOP•3mo ago
the network inspector shows this
No description
garyaustin
garyaustin•3mo ago
@LittleCat I thought you were seeing this on upload? Which does seem to have an issue. Your last image seems correct.
No description
inder
inder•3mo ago
This is my code and upload works fine
onClick={async () => {
console.log('file', file)
if (!file) return
const { data, error } = await supabase.storage.from('demo').upload(file.name, file, {
contentType: file.type,
})
if (error) return alert(error.message)

console.log(data)
}}
onClick={async () => {
console.log('file', file)
if (!file) return
const { data, error } = await supabase.storage.from('demo').upload(file.name, file, {
contentType: file.type,
})
if (error) return alert(error.message)

console.log(data)
}}
No description
LittleCat
LittleCatOP•3mo ago
yeah. it's an issue with my code. this simple code works out of the box. I will have to do some digging
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload File to Supabase</title>
</head>
<body>
<h1>Upload File to Supabase Storage</h1>
<input type="file" id="fileInput" />
<button onclick="uploadFile()">Upload</button>

<script src="https://cdn.jsdelivr.net/npm/@supabase/[email protected]/+esm" type="module"></script>

<script type="module">
const SUPABASE_URL = '';
const SUPABASE_KEY = '';
const BUCKET = '';

const { createClient } = await import('https://cdn.jsdelivr.net/npm/@supabase/[email protected]/+esm');
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);

window.uploadFile = async function () {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
if (!file) {
alert("Please select a file first.");
return;
}

const filePath = `users/abc/testUpload/${file.name}`;

const { data, error } = await supabase
.storage
.from(BUCKET)
.upload(filePath, file);

if (error) {
console.error('Upload error:', error);
alert('Upload failed.');
} else {
alert('Upload successful!');
console.log('Uploaded file data:', data);
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload File to Supabase</title>
</head>
<body>
<h1>Upload File to Supabase Storage</h1>
<input type="file" id="fileInput" />
<button onclick="uploadFile()">Upload</button>

<script src="https://cdn.jsdelivr.net/npm/@supabase/[email protected]/+esm" type="module"></script>

<script type="module">
const SUPABASE_URL = '';
const SUPABASE_KEY = '';
const BUCKET = '';

const { createClient } = await import('https://cdn.jsdelivr.net/npm/@supabase/[email protected]/+esm');
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);

window.uploadFile = async function () {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
if (!file) {
alert("Please select a file first.");
return;
}

const filePath = `users/abc/testUpload/${file.name}`;

const { data, error } = await supabase
.storage
.from(BUCKET)
.upload(filePath, file);

if (error) {
console.error('Upload error:', error);
alert('Upload failed.');
} else {
alert('Upload successful!');
console.log('Uploaded file data:', data);
}
}
</script>
</body>
</html>
thank you for your help. I found the bug
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
{
auth: {
persistSession: true,
autoRefreshToken: true,
},
global: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'apikey': process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
},
},
db: {
schema: 'public'
}
}
);
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
{
auth: {
persistSession: true,
autoRefreshToken: true,
},
global: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'apikey': process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
},
},
db: {
schema: 'public'
}
}
);
The issue is that I added global headers to my createClient code. Removing the Content-Type header will upload my file successfully in the correct mime type.
garyaustin
garyaustin•3mo ago
Crap. That is a first. So it replaces whatever storage comes up with. Why are you setting any of those though? apikey is set by Supabase. Accept should also be set properly.
LittleCat
LittleCatOP•3mo ago
😳 I was vibe coding for a bit since this is boilerplate code

Did you find this page helpful?