IceWhaleTech/CasaOS · error

ParseFileHeader fail:%s

Error message

ParseFileHeader fail:%s

What it means

ParseFromHead found the boundary and the CRLFCRLF header terminator, but the nested ParseFileHeader call failed to extract a valid header map from the buffered bytes. The returned error embeds the raw header slice so the developer can see exactly which bytes were unparseable.

Source

Thrown at pkg/utils/file/file.go:755

		read_total += read_len
		if !found_boundary {
			boundary_loc = bytes.LastIndex(read_data[:read_total], boundary)
			if boundary_loc == -1 {
				continue
			}
			found_boundary = true
		}
		start_loc := boundary_loc + len(boundary)
		fmt.Println(string(read_data))
		file_head_loc := bytes.Index(read_data[start_loc:read_total], []byte("\r\n\r\n"))
		if file_head_loc == -1 {
			continue
		}
		file_head_loc += start_loc
		ret := false
		headMap, ret := ParseFileHeader(read_data, boundary)
		if !ret {
			return headMap, nil, fmt.Errorf("ParseFileHeader fail:%s", string(read_data[start_loc:file_head_loc]))
		}
		return headMap, read_data[file_head_loc+4 : read_total], nil
	}
	return nil, nil, fmt.Errorf("reach to sream EOF")
}

View on GitHub (pinned to 0d3b2f444e)

Solutions

  1. Inspect the header bytes included in the error message — they show the exact malformed Content-Disposition.
  2. Fix the client to use a standard multipart writer (Go mime/multipart.Writer, curl -F) so headers are well-formed CRLF-terminated.
  3. Make ParseFileHeader more lenient (case-insensitive header names, optional filename) if you must accept loose clients.
  4. Reject with HTTP 400 and a clear message instead of retrying — the body will not change.
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check the part header region before parsing
if !bytes.Contains(readData[startLoc:readTotal], []byte("Content-Disposition")) {
	return errors.New("multipart part is missing Content-Disposition")
}

Try / catch

headMap, data, err := file.ParseFromHead(buf, 0, boundary, stream)
if err != nil && strings.Contains(err.Error(), "ParseFileHeader fail") {
	// header bytes are embedded in the error — log them and reject with 400
	log.Warn("bad multipart header", zap.String("header", err.Error()))
	return http.StatusBadRequest, errors.New("malformed multipart header")
}

Prevention

When it happens

Trigger: A multipart part whose Content-Disposition header is malformed — missing 'name='/'filename=' parameters, wrong field ordering, or binary garbage between the boundary and the CRLFCRLF terminator — when ParseFileHeader is called with the buffer and boundary.

Common situations: Non-browser clients (curl scripting, custom SDKs) sending hand-built multipart headers; header lines with bare LF instead of CRLF; charset issues; truncated body where the header region is cut mid-line.

Related errors


AI-assisted analysis of IceWhaleTech/CasaOS@0d3b2f444e (2026-08-15). Data as JSON: /api/errors/3f96efc30702e9cd. Report an issue: GitHub.