valyala/fasthttp · error

cannot open compressed file %q: %w

Error message

cannot open compressed file %q: %w

What it means

newCompressedFSFile opens an existing compressed cache file (original path + compressed suffix) to serve it from disk cache. If the filesystem Open fails, this error wraps the cause. This typically happens when the compressed file disappeared between the existence check and the open, or it was never readable.

Source

Thrown at fs.go:1867

	ff := &fsFile{
		h:               h,
		dirIndex:        dirIndex,
		contentType:     contentType,
		contentLength:   len(dirIndex),
		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)

View on GitHub (pinned to c96f600972)

Solutions

  1. Check the wrapped cause: fs.ErrNotExist means the cache file vanished — retry the request so fasthttp recompresses it.
  2. Exclude fasthttp cache files (CompressedFileSuffix pattern) from deploy rsync --delete and cleanup jobs.
  3. Ensure the service user can read the static root and cache files.
  4. If on NFS, remount or move the static root to local disk to avoid stale handles.

Example fix

// before: rsync --delete purges .fasthttp.gz cache during deploys
// rsync -a --delete ./dist/ /srv/www/
// after: keep cache files
// rsync -a --delete --exclude='*.fasthttp.*' ./dist/ /srv/www/
Defensive patterns

Strategy: retry

Validate before calling

compressedPath := path + ".fasthttp." + ext
if _, err := os.Stat(compressedPath); err != nil {
    // cache missing: either pre-generate or accept regeneration on retry
}

Try / catch

if strings.Contains(err.Error(), "cannot open compressed file") && errors.Is(err, fs.ErrNotExist) {
    // retry once: fasthttp will recreate the cache file
}

Prevention

When it happens

Trigger: A request hits the serve-from-compressed-cache path where the .fasthttp.* cache file was deleted by a concurrent cleanup or overwritten deploy between lookup and Open; or the compressed file exists but the process lost read permission.

Common situations: Deploy scripts rsyncing static roots with --delete while the server runs; external cache cleaners; permission changes after rotating service users; NFS 'stale file handle' on the cache file.

Related errors


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