Budibase/budibase · error · Error
Plugin must be compressed into a gzipped tarball.
Error message
Plugin must be compressed into a gzipped tarball.
What it means
Plugins must be distributed as gzipped tarballs. fileUpload checks the original filename ends with ".tar.gz" and rejects anything else with this message, before attempting extractTarball. This ensures the archive can be extracted and plugin metadata read safely.
Source
Thrown at packages/server/src/api/controllers/plugin/file.ts:17
import {
createTempFolder,
deleteFolderFileSystem,
getPluginMetadata,
extractTarball,
} from "../../../utilities/fileSystem"
import { KoaFile } from "@budibase/types"
export async function fileUpload(file: KoaFile) {
const filename = file.originalFilename
const filePath = file.filepath
if (!filename || !filePath) {
throw new Error("File is not valid - cannot upload.")
}
if (!filename.endsWith(".tar.gz")) {
throw new Error("Plugin must be compressed into a gzipped tarball.")
}
const path = createTempFolder(filename.split(".tar.gz")[0])
try {
await extractTarball(filePath, path)
return await getPluginMetadata(path)
} catch (err) {
deleteFolderFileSystem(path)
throw err
}
}
View on GitHub (pinned to a81a902e9a)
Solutions
- Repackage the plugin: tar -czf your-plugin.tar.gz <plugin-folder-or-files>
- Verify the filename ends exactly in .tar.gz (rename .tgz if needed)
- Confirm the archive actually contains the plugin.json/manifest at the expected location
- Re-upload the correctly packaged tarball
Example fix
// before zip -r plugin.zip dist/ # rejected // after tar -czf plugin.tar.gz dist/
Defensive patterns
Strategy: validation
Validate before calling
const name = file.name
if (!name.endsWith(".tar.gz")) {
throw new Error(`Plugin must be a .tar.gz; got ${name}`)
}
Type guard
const isTarGz = (name: string): name is `${string}.tar.gz` =>
name.endsWith(".tar.gz")
Try / catch
try {
await api.post("/api/plugins", form)
} catch (err) {
if (err.message === "Plugin must be compressed into a gzipped tarball.") {
// repackage: tar -czf plugin.tar.gz dist/
} else { throw err }
}
Prevention
- Package plugins with tar -czf, never zip
- Keep the .tar.gz extension (don't let tools save as .tgz)
- Verify archive contents (plugin manifest at expected path) before upload
- Document packaging steps in the plugin repo README
When it happens
Trigger: Uploading a plugin file with any extension other than .tar.gz — e.g. .zip, .tgz (without the full suffix), plain .tar, or a renamed file whose extension doesn't match its contents.
Common situations: Packaging a plugin with zip instead of tar czf; renaming .tgz to .tar.gz incorrectly or forgetting the rename; downloading a release asset that was decompressed by the browser; macOS squashing the extension to .tgz.
Related errors
- File is not valid - cannot upload.
- Stream to upload is invalid/undefined
- package.json is missing one of 'name', 'version' or 'descrip
- Plugin missing .js file.
- Invalid Github URL
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/53c8b5ec038bc10a.
Report an issue: GitHub.