valyala/fasthttp · error
cannot open already opened file: %w
Error message
cannot open already opened file: %w
What it means
bigFileReader lazily (re)opens the underlying file via ff.h.filesystem.Open when a request needs the file content, wrapping any open failure. The wording means: fasthttp believed the file was already open/available but the actual OS-level open failed, so the original error is wrapped with %w.
Source
Thrown at fs.go:721
}
var r io.Reader
ff.bigFilesLock.Lock()
n := len(ff.bigFiles)
if n > 0 {
r = ff.bigFiles[n-1]
ff.bigFiles = ff.bigFiles[:n-1]
}
ff.bigFilesLock.Unlock()
if r != nil {
return r, nil
}
f, err := ff.h.filesystem.Open(ff.filename)
if err != nil {
return nil, fmt.Errorf("cannot open already opened file: %w", err)
}
return &bigFileReader{
f: f,
ff: ff,
r: f,
}, nil
}
func (ff *fsFile) Release() {
if ff.f != nil {
_ = ff.f.Close()
if ff.isBig() {
ff.bigFilesLock.Lock()
for _, r := range ff.bigFiles {
_ = r.f.Close()
}
ff.bigFilesLock.Unlock()View on GitHub (pinned to c96f600972)
Solutions
- Log the wrapped inner error (%w) to see the real cause (ENOENT vs EACCES vs EMFILE)
- If ENOENT: the file disappeared mid-request — re-check your deploy/rotation process or disable aggressive caching of file handles
- If EMFILE: raise the ulimit -n / rlimit nofile for the server process
- If EACCES: restore read permissions on the file and execute permission on its directories for the fasthttp process user
Example fix
// diagnose
if _, err := os.ReadFile(path); err != nil {
log.Printf("open failed: %v", err) // reveals ENOENT/EACCES/EMFILE wrapped by this error
} Defensive patterns
Strategy: retry
Validate before calling
if fi, err := os.Stat(path); err != nil || !fi.Mode().IsRegular() {
return fmt.Errorf("file not servable: %s", path)
} Type guard
func isServableFile(path string) bool {
fi, err := os.Stat(path)
return err == nil && fi.Mode().IsRegular()
} Try / catch
content, err := handler(ctx)
if err != nil && strings.Contains(err.Error(), "cannot open already opened file") {
if errors.Is(err, syscall.EMFILE) { /* raise fd limit / shed load */ }
if errors.Is(err, fs.ErrNotExist) { /* file vanished: re-lookup or 404 */ }
} Prevention
- Raise RLIMIT_NOFILE for high-traffic file servers
- Keep file rotation and serving windows disjoint (rotate atomically via rename)
- Run the server with a user that has read access to all served trees
- Alert on this error: it usually signals a race between the OS and your deploy tooling
When it happens
Trigger: Serving a large file (> h.cacheSizes threshold) via FileServer/FS handler when the file is deleted, permissions change, or the path becomes unreadable between the stat/lru lookup and the actual Open call — a TOCTOU race, or a filesystem that refuses open (EACCES, EMFILE).
Common situations: File rotated/deleted by a deploy or log cleaner while being served; directory permissions tightened after server start; fd limits exhausted (too many open files) on busy servers.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- cannot open file %q: %w
- must implement seek
- must implement readat
- directory index required
- no 'create file' permissions
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/55af194ebd6c567d.
Report an issue: GitHub.