valyala/fasthttp · error
cannot determine absolute path for %q: %v
Error message
cannot determine absolute path for %q: %v
What it means
During on-the-fly file compression, fasthttp computes the absolute path of the compressed cache file (original path + compressed suffix) so it can acquire a per-path file lock. filepath.Abs failed, which is rare and only happens when Getwd fails on a relative path. The opened source file is closed and the wrapped filepath error is reported with %v.
Source
Thrown at fs.go:1712
}
compressedFilePath := h.filePathToCompressed(filePath)
if _, ok := h.filesystem.(*osFS); !ok {
return h.newCompressedFSFileCache(f, fileInfo, compressedFilePath, fileEncoding)
}
if compressedFilePath != filePath {
if err := os.MkdirAll(filepath.Dir(compressedFilePath), 0o750); err != nil {
return nil, err
}
}
compressedFilePath += h.compressedFileSuffixes[fileEncoding]
absPath, err := filepath.Abs(compressedFilePath)
if err != nil {
_ = f.Close()
return nil, fmt.Errorf("cannot determine absolute path for %q: %v", compressedFilePath, err)
}
flock := acquireFileLock(absPath)
flock.mu.Lock()
defer func() {
flock.mu.Unlock()
releaseFileLock(absPath, flock)
}()
return h.compressFileNolock(f, fileInfo, filePath, compressedFilePath, fileEncoding)
}
func (h *fsHandler) compressFileNolock(
f fs.File, fileInfo fs.FileInfo, filePath, compressedFilePath, fileEncoding string,
) (*fsFile, error) {
// Attempt to open compressed file created by another concurrent
// goroutine.
// It is safe opening such a file, since the file creation
// is guarded by file mutex - see getFileLock call.View on GitHub (pinned to c96f600972)
Solutions
- Use absolute paths: set FS.Root to an absolute directory or pass absolute file paths to SendFile.
- Ensure the process working directory exists (start the binary from a valid dir; avoid deleting the cwd).
- Configure FS.AbsPathToLocalPath / AbsPath so fasthttp resolves to absolute paths itself.
- Inspect the wrapped error: a Getwd failure like 'no such file or directory' confirms the cwd problem.
Example fix
// before
fs := &fasthttp.FS{Root: "static"}
// after
absRoot, err := filepath.Abs("static")
if err != nil { panic(err) }
fs := &fasthttp.FS{Root: absRoot} Defensive patterns
Strategy: validation
Validate before calling
abs, err := filepath.Abs(root)
if err != nil {
panic("working directory invalid: " + err.Error())
}
fs := &fasthttp.FS{Root: abs} Try / catch
if strings.Contains(err.Error(), "cannot determine absolute path") {
// restart process from a valid working directory or use absolute roots
} Prevention
- Always configure FS.Root with an absolute path.
- Never delete the process working directory at runtime.
- In containers, set WORKDIR to a persistent, existing directory.
When it happens
Trigger: Calling the FS handler with a relative file path (no leading '/' and no AbsPath configured) while the process's working directory has been deleted, or in environments where os.Getwd fails (removed cwd, restricted sandbox).
Common situations: Container/sandbox where the working directory was deleted at runtime; serving files with relative paths after a chdir-based deploy wiped the original cwd; running tests that os.Chdir into temp dirs later removed.
Related errors
- cannot open compressed file %q: %w
- cannot obtain info for compressed file %q: %w
- must implement seek
- must implement readat
- directory index required
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/37be3c271d0247d9.
Report an issue: GitHub.