{"record":{"id":"c22524bfe6bebffb","repo":"valyala/fasthttp","slug":"cannot-read-header-of-the-file-q-w","errorCode":null,"errorMessage":"cannot read header of the file %q: %w","messagePattern":"cannot read header of the file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fs.go","lineNumber":1842,"sourceCode":"\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error when compressing file %q: %w\", filePath, err)\n\t}\n\n\tseeker, ok := f.(io.Seeker)\n\tif !ok {\n\t\treturn nil, errors.New(\"seek is not implemented\")\n\t}\n\tif _, err = seeker.Seek(0, io.SeekStart); err != nil {\n\t\treturn nil, err\n\t}\n\n\text := fileExtension(fileInfo.Name(), false, h.compressedFileSuffixes[fileEncoding])\n\tcontentType := mime.TypeByExtension(ext)\n\tif contentType == \"\" {\n\t\tdata, err := readFileHeader(f, false, fileEncoding)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot read header of the file %q: %w\", fileInfo.Name(), err)\n\t\t}\n\t\tcontentType = http.DetectContentType(data)\n\t}\n\n\tdirIndex := w.B\n\tlastModified := fileInfo.ModTime()\n\tff := &fsFile{\n\t\th:               h,\n\t\tdirIndex:        dirIndex,\n\t\tcontentType:     contentType,\n\t\tcontentLength:   len(dirIndex),\n\t\tcompressed:      true,\n\t\tlastModified:    lastModified,\n\t\tlastModifiedStr: AppendHTTPDate(nil, lastModified),\n\n\t\tt: time.Now(),\n\t}\n","sourceCodeStart":1824,"sourceCodeEnd":1860,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/fs.go#L1824-L1860","documentation":"When building the *fsFile for a (possibly compressed) file, fasthttp needs a Content-Type. If mime.TypeByExtension can't determine it from the extension, it reads the first bytes of the file (readFileHeader, decompressing if needed) to sniff the type via http.DetectContentType. If that header read fails, this error wraps the cause with the file's base name. The file cannot be served without a content type path succeeding.","triggerScenarios":"Requesting a file whose extension is unknown to mime.TypeByExtension AND whose content cannot be read/decompressed for sniffing — e.g. corrupted compressed cache file, read error mid-header, or a file that shrank to 0 bytes after Stat.","commonSituations":"Serving files without extensions that were truncated or corrupted; a stale/corrupt fasthttp compressed cache file (e.g. .fasthttp.gz) truncated by a crash; deploying partially uploaded files.","solutions":["Check the wrapped cause; if reading the compressed cache failed, delete the stale compressed cache files (suffix .fasthttp.*) and let them regenerate.","Ensure served files are fully written (atomic uploads: write temp + rename).","Add the file's extension mapping via mime.AddExtensionType so sniffing isn't needed.","Verify the file is non-empty and readable by the server user."],"exampleFix":"// before: extensionless, truncated file causes sniff failure\n// after: register MIME and ensure atomic writes\nmime.AddExtensionType(\"\", \"application/octet-stream\")\n// upload pattern:\n// os.WriteFile(f+\".tmp\", data, 0o644); os.Rename(f+\".tmp\", f)","handlingStrategy":"validation","validationCode":"mime.AddExtensionType(\"\", \"application/octet-stream\")\nif fi, err := os.Stat(path); err != nil || fi.Size() == 0 {\n    // reject empty/missing files before serving\n}","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"cannot read header of the file\") {\n    // delete stale *.fasthttp.* cache and serve 500/404; files will regenerate\n}","preventionTips":["Register MIME types for all served extensions (mime.AddExtensionType).","Write files atomically (temp + rename) so sniffing never sees truncated data.","Purge corrupt compressed cache files after crashes or partial deploys."],"tags":["fasthttp","content-type","mime","file-reading"],"backgroundTag":"mime-sniff-failed","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}