{"id":"23184fe53c514092","repo":"gin-gonic/gin","slug":"unsupported-field-type-for-multipart-fileheader","errorCode":null,"errorMessage":"unsupported field type for multipart.FileHeader","messagePattern":"unsupported field type for multipart\\.FileHeader","errorType":"validation","errorClass":"ErrMultiFileHeader","httpStatus":400,"severity":"error","filePath":"binding/multipart_form_mapping.go","lineNumber":20,"sourceCode":"// Use of this source code is governed by a MIT style\n// license that can be found in the LICENSE file.\n\npackage binding\n\nimport (\n\t\"errors\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"reflect\"\n)\n\ntype multipartRequest http.Request\n\nvar _ setter = (*multipartRequest)(nil)\n\nvar (\n\t// ErrMultiFileHeader multipart.FileHeader invalid\n\tErrMultiFileHeader = errors.New(\"unsupported field type for multipart.FileHeader\")\n\n\t// ErrMultiFileHeaderLenInvalid array for []*multipart.FileHeader len invalid\n\tErrMultiFileHeaderLenInvalid = errors.New(\"unsupported len of array for []*multipart.FileHeader\")\n)\n\n// TrySet tries to set a value by the multipart request with the binding a form file\nfunc (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (bool, error) {\n\tif files := r.MultipartForm.File[key]; len(files) != 0 {\n\t\treturn setByMultipartFormFile(value, field, files)\n\t}\n\n\treturn setByForm(value, field, r.MultipartForm.Value, key, opt)\n}\n\nfunc setByMultipartFormFile(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSet bool, err error) {\n\tswitch value.Kind() {\n\tcase reflect.Ptr:\n\t\tswitch value.Interface().(type) {","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/gin-gonic/gin/blob/34dac209ffb6ef85cc78c5d217bbb7ad001d68fd/binding/multipart_form_mapping.go#L2-L38","documentation":"ErrMultiFileHeader is returned by setByMultipartFormFile (binding/multipart_form_mapping.go:60) when a multipart upload field maps to a struct field whose type is not one Gin's file binder recognises. Recognised types are *multipart.FileHeader, multipart.FileHeader, []multipart.FileHeader, []*multipart.FileHeader, [N]multipart.FileHeader, [N]*multipart.FileHeader.","triggerScenarios":"A multipart/form-data POST bound to a struct whose corresponding field is typed *os.File, io.Reader, string, []byte, or any custom struct — the file binder hits the default branch and returns this error.","commonSituations":"Expecting Gin to give you an open io.Reader or *os.File; typing the field as string expecting the filename; using a custom File wrapper struct instead of multipart.FileHeader.","solutions":["Declare the field as *multipart.FileHeader (single file) or []*multipart.FileHeader (multiple).","Open the file via header.Open() inside the handler if you need an io.Reader.","If you need only the filename/size, read it off the *multipart.FileHeader after binding."],"exampleFix":"// before\ntype Upload struct {\n    File io.Reader `form:\"file\"`\n}\n// after\ntype Upload struct {\n    File *multipart.FileHeader `form:\"file\"`\n}\n// then in handler: src, _ := form.File.Open(); defer src.Close()","handlingStrategy":"type-guard","validationCode":"func isFileHeaderField(t reflect.Type) bool {\n    switch t {\n    case reflect.TypeOf(&multipart.FileHeader{}), reflect.TypeOf(multipart.FileHeader{}):\n        return true\n    }\n    if t.Kind() == reflect.Slice {\n        elem := t.Elem()\n        return elem == reflect.TypeOf(&multipart.FileHeader{}) || elem == reflect.TypeOf(multipart.FileHeader{})\n    }\n    if t.Kind() == reflect.Array {\n        elem := t.Elem()\n        return elem == reflect.TypeOf(&multipart.FileHeader{}) || elem == reflect.TypeOf(multipart.FileHeader{})\n    }\n    return false\n}","typeGuard":"var _ *multipart.FileHeader = (*multipart.FileHeader)(nil)","tryCatchPattern":"if err := c.ShouldBind(&form); err != nil {\n    if errors.Is(err, binding.ErrMultiFileHeader) {\n        c.AbortWithStatus(http.StatusBadRequest) // wrong field type for file\n        return\n    }\n}","preventionTips":["Always type file fields as *multipart.FileHeader or []*multipart.FileHeader.","Open the file with header.Open() — Gin does not give you an io.Reader directly.","Document expected field types next to the upload handler."],"tags":["binding","multipart","upload","go"],"analyzedSha":"34dac209ffb6ef85cc78c5d217bbb7ad001d68fd","analyzedAt":"2026-08-04T21:26:18.438Z","schemaVersion":2}