gotify/server · error

invalid file extension

Error message

invalid file extension

What it means

Even when the bytes pass the image sniff, the endpoint validates the filename extension against ValidApplicationImageExt. If filepath.Ext(file.Filename) is not in the allowlist (e.g. .svg, .bmp, .tiff, or no extension), the upload is rejected with this 400 error.

Source

Thrown at api/application.go:433

			file, err := ctx.FormFile("file")
			if err == http.ErrMissingFile {
				ctx.AbortWithError(400, errors.New("file with key 'file' must be present"))
				return
			} else if err != nil {
				ctx.AbortWithError(500, err)
				return
			}
			head := make([]byte, 261)
			open, _ := file.Open()
			open.Read(head)
			if !filetype.IsImage(head) {
				ctx.AbortWithError(400, errors.New("file must be an image"))
				return
			}

			ext := filepath.Ext(file.Filename)
			if !ValidApplicationImageExt(ext) {
				ctx.AbortWithError(400, errors.New("invalid file extension"))
				return
			}

			name := generateNonExistingImageName(a.ImageDir, func() string {
				return generateImageName() + ext
			})

			err = ctx.SaveUploadedFile(file, a.ImageDir+name)
			if err != nil {
				ctx.AbortWithError(500, err)
				return
			}

			if app.Image != "" {
				os.Remove(a.ImageDir + app.Image)
			}

			app.Image = name

View on GitHub (pinned to 14bfc25627)

Solutions

  1. Convert/rename the file to an allowlisted extension (typically .png, .jpg, .jpeg, .gif) before uploading
  2. Ensure the client preserves the original filename extension in the multipart part
  3. If the format should be allowed, extend the ValidApplicationImageExt allowlist server-side (and consider serving implications)
  4. Check the filename the client sends — some clients send 'blob' as the name

Example fix

// before
fd.append('file', file, 'image');
// after
fd.append('file', file, 'image.png');
Defensive patterns

Strategy: validation

Validate before calling

const allowed = ['.png', '.jpg', '.jpeg', '.gif'];
const ext = file.name.slice(file.name.lastIndexOf('.')).toLowerCase();
if (!allowed.includes(ext)) throw new Error(`extension ${ext} not allowed`);

Prevention

When it happens

Trigger: Uploading a valid image whose filename extension is not whitelisted (e.g. .svg, .avif, .heic, or extensionless files); uploading with a filename that lost its extension during client processing.

Common situations: Browsers/Safari saving images as .jfif or .heic; files downloaded without extensions; animated SVG uploads; automation generating temp files without extensions.

Related errors


AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05). Data as JSON: /api/errors/8f92cf2b4995a376. Report an issue: GitHub.