valyala/fasthttp · error

cannot obtain info for compressed file %q: %w

Error message

cannot obtain info for compressed file %q: %w

What it means

Companion to [110]: after successfully opening a compressed cache file, fasthttp calls Stat to obtain its metadata (size, modtime) required to build the *fsFile. If Stat fails, the file is closed and this error wraps the cause. It indicates the cache file's metadata became unavailable right after a successful open.

Source

Thrown at fs.go:1872

		compressed:      true,
		lastModified:    lastModified,
		lastModifiedStr: AppendHTTPDate(nil, lastModified),

		t: time.Now(),
	}

	return ff, nil
}

func (h *fsHandler) newCompressedFSFile(filePath, fileEncoding string) (*fsFile, error) {
	f, err := h.filesystem.Open(filePath)
	if err != nil {
		return nil, fmt.Errorf("cannot open compressed file %q: %w", filePath, err)
	}
	fileInfo, err := f.Stat()
	if err != nil {
		_ = f.Close()
		return nil, fmt.Errorf("cannot obtain info for compressed file %q: %w", filePath, err)
	}
	return h.newFSFile(f, fileInfo, true, filePath, fileEncoding)
}

func (h *fsHandler) openFSFile(filePath string, mustCompress bool, fileEncoding string) (*fsFile, error) {
	filePathOriginal := filePath
	if mustCompress {
		filePath += h.compressedFileSuffixes[fileEncoding]
	}
	f, err := h.filesystem.Open(filePath)
	if err != nil {
		if mustCompress && errors.Is(err, fs.ErrNotExist) {
			return h.compressAndOpenFSFile(filePathOriginal, fileEncoding)
		}

		// If the file is not found and the path is empty, let's return errDirIndexRequired error.
		if filePath == "" && (errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrInvalid)) {
			return nil, errDirIndexRequired

View on GitHub (pinned to c96f600972)

Solutions

  1. Retry the request: fasthttp will re-open/re-compress; the race is usually transient.
  2. Stop concurrent deletion of compressed cache files (coordinate cleaners with deploys, use atomic renames).
  3. Check the wrapped cause: ESTALE/ENOENT points to NFS or removal races — move cache to local disk.
  4. Verify directory permissions on the static root haven't changed for the service user.

Example fix

// before: cron deleting cache while serving
// */5 * * * * find /srv/www -name '*.fasthttp.*' -delete
// after: remove the racy cleanup; let fasthttp manage/regenerate cache
fs := &fasthttp.FS{Root: "/srv/www", Compress: true}
Defensive patterns

Strategy: retry

Validate before calling

if fi, err := os.Stat(compressedPath); err != nil || fi.IsDir() {
    // cache file unavailable; skip or regenerate before serving
}

Try / catch

if strings.Contains(err.Error(), "cannot obtain info for compressed file") {
    // transient race; retry the request, fasthttp will rebuild the cache entry
}

Prevention

When it happens

Trigger: Stat failing on an already-open compressed cache file — concurrent deletion between Open and Stat (racing cleaner/deploy), permission change on the parent directory, or network filesystem errors (ESTALE) after open.

Common situations: Cache cleanup daemon removing .fasthttp.* files mid-request; NFS stale handles; containers where the static volume is unmounted/re-mounted during runtime.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/5b6b06f361ac5b01. Report an issue: GitHub.