IceWhaleTech/CasaOS · error

reach to sream EOF

Error message

reach to sream EOF

What it means

ParseFromHead read the input stream to EOF without ever finding both the boundary and the CRLFCRLF header terminator (or the header parse never succeeded). The multipart part's header section was never completed within the stream, so parsing fails with 'reach to sream EOF' (sic).

Source

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

				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. Check the body was not consumed before parsing — read once and pass the same reader, or buffer r.Body first.
  2. Verify proxy limits (client_max_body_size, request buffering) are not truncating large uploads.
  3. Confirm the boundary matches the Content-Type parameter (same root cause as 'not found boundary').
  4. Detect short reads early by comparing Content-Length against bytes actually read.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the body is not already consumed and has expected length
if r.Body == nil { return http.StatusBadRequest, errors.New("empty body") }
if r.ContentLength > 0 {
	buf, err := io.ReadAll(io.LimitReader(r.Body, r.ContentLength))
	if int64(len(buf)) != r.ContentLength { return http.StatusBadRequest, errors.New("truncated upload body") }
}

Try / catch

headMap, data, err := file.ParseFromHead(buf, 0, boundary, stream)
if err != nil {
	if strings.Contains(err.Error(), "reach to sream EOF") || strings.Contains(err.Error(), "EOF") {
		// truncated body or wrong boundary: fail the request; a retry needs the client to resend
		return http.StatusBadRequest, errors.New("upload incomplete")
	}
	return err
}

Prevention

When it happens

Trigger: The request body ends before a complete part header appears: truncated upload (client disconnected mid-request), empty body passed with a boundary expected, boundary string that never matches, or the stream already consumed by earlier code (e.g. r.Body read twice).

Common situations: Client connection dropped during upload; reverse proxy (nginx client_max_body_size) truncating the body; body already drained by logging middleware before ParseFromHead runs; mismatch between declared and actual boundary causing headers to be skipped forever.

Related errors


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