{"record":{"id":"363f04367656839d","repo":"valyala/fasthttp","slug":"cannot-open-file-q-w","errorCode":null,"errorMessage":"cannot open file %q: %w","messagePattern":"cannot open file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fs.go","lineNumber":1552,"sourceCode":"func (h *fsHandler) openIndexFile(ctx *RequestCtx, dirPath string, mustCompress bool, fileEncoding string) (*fsFile, error) {\n\tfor _, indexName := range h.indexNames {\n\t\tindexFilePath := indexName\n\t\tif dirPath != \"\" {\n\t\t\tindexFilePath = dirPath + \"/\" + indexName\n\t\t}\n\n\t\tff, err := h.openFSFile(indexFilePath, mustCompress, fileEncoding)\n\t\tif err == nil {\n\t\t\treturn ff, nil\n\t\t}\n\t\tif mustCompress && err == errNoCreatePermission {\n\t\t\tctx.Logger().Printf(\"insufficient permissions for saving compressed file for %q. Serving uncompressed file. \"+\n\t\t\t\t\"Allow write access to the directory with this file in order to improve fasthttp performance\", indexFilePath)\n\t\t\tmustCompress = false\n\t\t\treturn h.openFSFile(indexFilePath, mustCompress, fileEncoding)\n\t\t}\n\t\tif !errors.Is(err, fs.ErrNotExist) {\n\t\t\treturn nil, fmt.Errorf(\"cannot open file %q: %w\", indexFilePath, err)\n\t\t}\n\t}\n\n\tif !h.generateIndexPages {\n\t\treturn nil, fmt.Errorf(\"cannot access directory without index page: directory %q\", dirPath)\n\t}\n\n\treturn h.createDirIndex(ctx, dirPath, mustCompress, fileEncoding)\n}\n\nvar (\n\terrDirIndexRequired   = errors.New(\"directory index required\")\n\terrNoCreatePermission = errors.New(\"no 'create file' permissions\")\n)\n\nfunc (h *fsHandler) createDirIndex(ctx *RequestCtx, dirPath string, mustCompress bool, fileEncoding string) (*fsFile, error) {\n\tw := &bytebufferpool.ByteBuffer{}\n","sourceCodeStart":1534,"sourceCodeEnd":1570,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/fs.go#L1534-L1570","documentation":"openIndexFile tries to open a pre-compressed or cached index file (e.g. index.html.gz) before falling back to the real index. If opening that index file fails for a reason other than fs.ErrNotExist (e.g. EACCES, EISDIR), the error is wrapped and returned rather than silently falling back.","triggerScenarios":"Directory request handled by fasthttp FS/FileServer where the index file path exists but cannot be opened: wrong permissions on index.html, index path is actually a directory, or an I/O error; also compressed-file paths with unreadable ACLs.","commonSituations":"Deploy leaves index.html owned by root with 0600 while the server runs as another user; a file literally named like the index path but being a directory; NFS/overlayfs transient I/O errors in containers.","solutions":["Log the wrapped inner error to see the real errno (EACCES vs EISDIR)","Fix permissions: chmod/chown index.html so the fasthttp process can read it","Ensure the path is a regular file, not a directory: ls -la the directory and rename/remove the conflicting entry","If you intentionally don't want index files, disable index page generation (GenerateIndexPages: false) so a clearer error is returned"],"exampleFix":"// before (server config with unreadable index)\nfs.New(fs.Config{Root: \"./static\"}) // index.html 0600 root-owned\n// after\n// chmod 644 ./static/index.html && chown www-data ./static/index.html\nfs.New(fs.Config{Root: \"./static\", GenerateIndexPages: true})","handlingStrategy":"fallback","validationCode":"if fi, err := os.Stat(indexPath); err != nil || !fi.Mode().IsRegular() || fi.Mode().Perm()&0o400 == 0 {\n    log.Printf(\"index file %s unreadable\", indexPath)\n}","typeGuard":"func readableRegularFile(path string) bool {\n    fi, err := os.Stat(path)\n    return err == nil && fi.Mode().IsRegular()\n}","tryCatchPattern":"if err := serveIndex(ctx, dir); err != nil {\n    if !errors.Is(err, fs.ErrNotExist) {\n        log.Printf(\"index open failed: %v\", err) // real errno is wrapped\n    }\n    http.Error(ctx, \"not found\", 404)\n}","preventionTips":["Chown/chmod index.html to match the fasthttp process user","Verify no directory shadows the index filename","Include an fs health check that Stats every configured index path at startup","Deploy files atomically with correct ownership"],"tags":["filesystem","permissions","file-server","fasthttp"],"backgroundTag":"file-open-failed","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}