{"record":{"id":"d31bff3d11e1ce0b","repo":"IceWhaleTech/CasaOS","slug":"reach-to-sream-eof","errorCode":null,"errorMessage":"reach to sream EOF","messagePattern":"reach to sream EOF","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/utils/file/file.go","lineNumber":759,"sourceCode":"\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfound_boundary = true\n\t\t}\n\t\tstart_loc := boundary_loc + len(boundary)\n\t\tfmt.Println(string(read_data))\n\t\tfile_head_loc := bytes.Index(read_data[start_loc:read_total], []byte(\"\\r\\n\\r\\n\"))\n\t\tif file_head_loc == -1 {\n\t\t\tcontinue\n\t\t}\n\t\tfile_head_loc += start_loc\n\t\tret := false\n\t\theadMap, ret := ParseFileHeader(read_data, boundary)\n\t\tif !ret {\n\t\t\treturn headMap, nil, fmt.Errorf(\"ParseFileHeader fail:%s\", string(read_data[start_loc:file_head_loc]))\n\t\t}\n\t\treturn headMap, read_data[file_head_loc+4 : read_total], nil\n\t}\n\treturn nil, nil, fmt.Errorf(\"reach to sream EOF\")\n}\n","sourceCodeStart":741,"sourceCodeEnd":761,"githubUrl":"https://github.com/IceWhaleTech/CasaOS/blob/0d3b2f444ec0193193cf03eef6d43c6e35b0183e/pkg/utils/file/file.go#L741-L761","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","solutions":["Check the body was not consumed before parsing — read once and pass the same reader, or buffer r.Body first.","Verify proxy limits (client_max_body_size, request buffering) are not truncating large uploads.","Confirm the boundary matches the Content-Type parameter (same root cause as 'not found boundary').","Detect short reads early by comparing Content-Length against bytes actually read."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the body is not already consumed and has expected length\nif r.Body == nil { return http.StatusBadRequest, errors.New(\"empty body\") }\nif r.ContentLength > 0 {\n\tbuf, err := io.ReadAll(io.LimitReader(r.Body, r.ContentLength))\n\tif int64(len(buf)) != r.ContentLength { return http.StatusBadRequest, errors.New(\"truncated upload body\") }\n}","typeGuard":null,"tryCatchPattern":"headMap, data, err := file.ParseFromHead(buf, 0, boundary, stream)\nif err != nil {\n\tif strings.Contains(err.Error(), \"reach to sream EOF\") || strings.Contains(err.Error(), \"EOF\") {\n\t\t// truncated body or wrong boundary: fail the request; a retry needs the client to resend\n\t\treturn http.StatusBadRequest, errors.New(\"upload incomplete\")\n\t}\n\treturn err\n}","preventionTips":["Read the request body exactly once; buffer it if multiple consumers need it","Raise proxy body-size limits (nginx client_max_body_size) for large uploads","Validate the boundary before parsing to avoid scanning to EOF on mismatched input"],"tags":["multipart","parsing","truncation","upload"],"backgroundTag":null,"analyzedSha":"0d3b2f444ec0193193cf03eef6d43c6e35b0183e","analyzedAt":"2026-08-15T13:27:57.821Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}