{"record":{"id":"eeebe4781a3fe9b3","repo":"appwrite/appwrite","slug":"storage-file-type-unsupported","errorCode":"storage_file_type_unsupported","errorMessage":"storage_file_type_unsupported","messagePattern":"storage_file_type_unsupported","errorType":"exception","errorClass":"Appwrite\\Extend\\Exception","httpStatus":400,"severity":"error","filePath":"src/Appwrite/Platform/Modules/Functions/Http/Deployments/Create.php","lineNumber":161,"sourceCode":"        }\n\n        $functionSizeLimit = (int) System::getEnv('_APP_COMPUTE_SIZE_LIMIT', '30000000');\n\n        if (isset($plan['deploymentSize'])) {\n            $functionSizeLimit = $plan['deploymentSize'] * 1000 * 1000;\n        }\n\n        $fileExt = new FileExt([FileExt::TYPE_GZIP]);\n        $fileSizeValidator = new FileSize($functionSizeLimit);\n        $upload = new Upload();\n\n        // Make sure we handle a single file and multiple files the same way\n        $fileName = (\\is_array($file['name']) && isset($file['name'][0])) ? $file['name'][0] : $file['name'];\n        $fileTmpName = (\\is_array($file['tmp_name']) && isset($file['tmp_name'][0])) ? $file['tmp_name'][0] : $file['tmp_name'];\n        $fileSize = (\\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size'];\n\n        if (!$fileExt->isValid($file['name'])) { // Check if file type is allowed\n            throw new Exception(Exception::STORAGE_FILE_TYPE_UNSUPPORTED);\n        }\n\n        $contentRange = $request->getHeaderLine('content-range');\n        $deploymentId = ID::unique();\n        $chunk = 1;\n        $chunks = 1;\n\n        if (!empty($contentRange)) {\n            $start = $request->getContentRangeStart();\n            $end = $request->getContentRangeEnd();\n            $fileSize = $request->getContentRangeSize();\n            $deploymentId = $request->getHeaderLine('x-appwrite-id', $deploymentId);\n            // TODO make `end >= $fileSize` in next breaking version\n            if (is_null($start) || is_null($end) || is_null($fileSize) || $end > $fileSize) {\n                throw new Exception(Exception::STORAGE_INVALID_CONTENT_RANGE);\n            }\n\n            $chunks = (int) ceil($fileSize / APP_LIMIT_UPLOAD_CHUNK_SIZE);","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/appwrite/appwrite/blob/0cefd0615350e1914a29caeef3342fd620a60045/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Create.php#L143-L179","documentation":"Returned synchronously (HTTP 400, code storage_file_type_unsupported) when the uploaded code file's extension is not in the allowed gzip set. The endpoint builds a FileExt validator restricted to FileExt::TYPE_GZIP, so only gzip-family file names (e.g. .tar.gz, .tgz, .gz) pass; a .zip or extension-less file is rejected before size checks.","triggerScenarios":"POST /v1/functions/:id/deployments with a file named code.zip, archive.zip, or any name whose extension is not a gzip type; also when the multipart filename loses its extension through SDK misconfiguration.","commonSituations":"Developers zipping code with zip instead of tar+gzip, CI pipelines producing .zip artifacts, filenames mangled by proxies, or the multipart filename set to a blob without extension.","solutions":["Package the deployment as a gzipped tarball: tar -czf code.tar.gz .","Name the file with a gzip extension (.tar.gz / .tgz / .gz) in the multipart part","If you have a zip, convert: gunzip is not needed — unzip then tar -czf","Verify the SDK InputFile keeps the file name with extension"],"exampleFix":"# before: zip archive\nzip -r code.zip . && curl -F 'code=@code.zip' ...\n\n# after: gzip tarball\ntar -czf code.tar.gz . && curl -F 'code=@code.tar.gz' -F 'entrypoint=index.js' -F 'activate=true' ...","handlingStrategy":"validation","validationCode":"const GZIP_EXT = /\\.(tar\\.gz|tgz|gz)$/i;\nif (!GZIP_EXT.test(fileName)) throw new Error('package the deployment as a gzip tarball (.tar.gz)');\nform.append('code', file, 'code.tar.gz');","typeGuard":"const isGzipArchive = (name) => /\\.(tar\\.gz|tgz|gz)$/i.test(name);","tryCatchPattern":"try { await functions.createDeployment(functionId, file); } catch (e) { if (e.code === 'storage_file_type_unsupported') { /* repackage as tar.gz and retry */ } else throw e; }","preventionTips":["Standardize build output on tar -czf code.tar.gz","Do not send .zip archives to the deployment endpoint","Verify the SDK preserves the filename extension"],"tags":["functions","deployments","upload","file-type","gzip"],"backgroundTag":"unsupported-file-type","analyzedSha":"0cefd0615350e1914a29caeef3342fd620a60045","analyzedAt":"2026-08-18T21:34:56.994Z","contentChangedAt":"2026-08-18T21:34:56.994Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}