{"record":{"id":"8aff3122e3520e74","repo":"dutchcoders/transfer.sh","slug":"clamav-prescan-found-a-virus","errorCode":null,"errorMessage":"Clamav prescan found a virus","messagePattern":"Clamav prescan found a virus","errorType":"http","errorClass":null,"httpStatus":412,"severity":"warning","filePath":"server/handlers.go","lineNumber":512,"sourceCode":"\t\t\t}\n\n\t\t\tif s.maxUploadSize > 0 && contentLength > s.maxUploadSize {\n\t\t\t\ts.logger.Print(\"Entity too large\")\n\t\t\t\thttp.Error(w, http.StatusText(http.StatusRequestEntityTooLarge), http.StatusRequestEntityTooLarge)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif s.performClamavPrescan {\n\t\t\t\tstatus, err := s.performScan(file.Name())\n\t\t\t\tif err != nil {\n\t\t\t\t\ts.logger.Printf(\"%s\", err.Error())\n\t\t\t\t\thttp.Error(w, \"Could not perform prescan\", http.StatusInternalServerError)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif status != clamavScanStatusOK {\n\t\t\t\t\ts.logger.Printf(\"prescan positive: %s\", status)\n\t\t\t\t\thttp.Error(w, \"Clamav prescan found a virus\", http.StatusPreconditionFailed)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmetadata := metadataForRequest(contentType, contentLength, s.randomTokenLength, r)\n\n\t\t\tbuffer := &bytes.Buffer{}\n\t\t\tif err := json.NewEncoder(buffer).Encode(metadata); err != nil {\n\t\t\t\ts.logger.Printf(\"%s\", err.Error())\n\t\t\t\thttp.Error(w, \"Could not encode metadata\", http.StatusInternalServerError)\n\n\t\t\t\treturn\n\t\t\t} else if err := s.storage.Put(r.Context(), token, fmt.Sprintf(\"%s.metadata\", filename), buffer, \"text/json\", uint64(buffer.Len())); err != nil {\n\t\t\t\ts.logger.Printf(\"%s\", err.Error())\n\t\t\t\thttp.Error(w, \"Could not save metadata\", http.StatusInternalServerError)\n\n\t\t\t\treturn\n\t\t\t}","sourceCodeStart":494,"sourceCodeEnd":530,"githubUrl":"https://github.com/dutchcoders/transfer.sh/blob/c37bfd95797fd6da8a6da53fc13d191994b3f687/server/handlers.go#L494-L530","documentation":"In postHandler, when the server runs with ClamAV prescan enabled (ClamavPort configured), each uploaded multipart part is written to a temp file and scanned via performScan before storage. If the ClamAV daemon reports any status other than OK, the server rejects the upload with HTTP 412 Precondition Failed and this message. It is an intentional server-side antivirus policy rejection, not a crash.","triggerScenarios":"POST a multipart upload to the server while the operator has ClamAV prescan enabled and the uploaded file matches a ClamAV signature (EICAR test string, actual malware, or a false-positive signature).","commonSituations":"Uploading EICAR test files during integration testing; hosting scenarios where users share binaries or documents that trip heuristic ClamAV signatures; security-sensitive deployments (public file-sharing instances) that routinely reject flagged content.","solutions":["Remove the virus signature or stop uploading the flagged file; the rejection is by design.","Verify with `clamscan <file>` locally whether the detection is a true positive or a false positive.","If it is a false positive, update ClamAV virus definitions (freshclam) or submit a false-positive report to ClamAV.","As an operator, disable prescan (unset the ClamAV port option) if the security policy allows unscanned uploads.","Handle HTTP 412 in the client by surfacing the antivirus rejection to the end user instead of retrying."],"exampleFix":"// before: blindly retrying the upload\nresp, _ := http.Post(url, \"application/octet-stream\", file)\n// after: detect the 412 antivirus rejection and inform the user\nresp, _ := http.Post(url, \"application/octet-stream\", file)\nif resp != nil && resp.StatusCode == http.StatusPreconditionFailed {\n    return fmt.Errorf(\"upload rejected: file failed ClamAV prescan\")\n}","handlingStrategy":"validation","validationCode":"// Scan locally with clamscan before uploading\nfunc passesPrescan(path string) bool {\n    out, err := exec.Command(\"clamscan\", \"--no-summary\", path).Output()\n    if err != nil {\n        return false // clamscan exits non-zero when a virus is found\n    }\n    _ = out\n    return true\n}","typeGuard":null,"tryCatchPattern":"resp, err := http.Post(url, mime, body)\nif err == nil && resp.StatusCode == http.StatusPreconditionFailed {\n    return fmt.Errorf(\"upload rejected by server antivirus prescan\")\n}","preventionTips":["Pre-scan files with clamscan/ClamAV locally before uploading to prescan-enabled servers.","Never upload EICAR test strings to production endpoints.","Treat HTTP 412 as terminal — do not retry the same file.","Check ClamAV false-positive reports before blaming your file."],"tags":["http","clamav","antivirus","upload","server"],"backgroundTag":"clamav-virus-detected","analyzedSha":"c37bfd95797fd6da8a6da53fc13d191994b3f687","analyzedAt":"2026-09-05T10:21:07.548Z","contentChangedAt":"2026-09-05T10:21:07.548Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}