rqlite/rqlite · error
failed to write decompressed data to file: %v
Error message
failed to write decompressed data to file: %v
What it means
The Dechunker reassembles gzip-compressed chunks into a single file. This error is wrapped by WriteChunk when io.Copy fails while writing decompressed bytes from the gzip reader into the underlying temp file. It indicates the disk write failed mid-stream, so the reassembled file is incomplete or unwritable.
Source
Thrown at command/chunking/dechunker.go:58
} else if d.streamID != chunk.StreamId {
return false, fmt.Errorf("chunk has unexpected stream ID: expected %s but got %s", d.streamID, chunk.StreamId)
}
if chunk.SequenceNum != d.seqNum+1 {
return false, fmt.Errorf("chunks received out of order: expected %d but got %d", d.seqNum+1, chunk.SequenceNum)
}
d.seqNum = chunk.SequenceNum
if chunk.Data != nil {
buf := bytes.NewBuffer(chunk.Data)
gzw, err := gzip.NewReader(buf)
if err != nil {
return false, fmt.Errorf("failed to create gzip reader: %v", err)
}
defer gzw.Close()
if _, err := io.Copy(d.file, gzw); err != nil {
return false, fmt.Errorf("failed to write decompressed data to file: %v", err)
}
}
return chunk.IsLast, nil
}
// Close closes the Dechunker and returns the file path containing the reassembled data.
func (d *Dechunker) Close() (string, error) {
if err := d.file.Close(); err != nil {
return "", fmt.Errorf("failed to close file: %v", err)
}
return d.filePath, nil
}
// DechunkerManager manages Dechunkers.
type DechunkerManager struct {
dir string
mu sync.MutexView on GitHub (pinned to 7586a4d1bd)
Solutions
- Free disk space on the directory backing the Dechunker (usually the node's data dir) and retry the upload from the first chunk
- Check filesystem permissions and mount health (df, dmesg for I/O errors)
- Inspect the wrapped inner error (%v) to distinguish ENOSPC from EIO or a closed-file bug
- If using containers, verify the volume quota and increase it
Example fix
// caller before/after: check space before a large chunked upload
// before
dechunker.WriteChunk(chunk)
// after
if free, _ := diskFree(dataDir); free < expectedSize {
return fmt.Errorf("insufficient disk space in %s: need ~%d bytes", dataDir, expectedSize)
}
err := decomposer.Write(rl, dechunkerFn) // then handle error, delete partial file Defensive patterns
Strategy: try-catch
Validate before calling
// Go: check free space on the dechunker directory before large transfers
func hasFreeSpace(dir string, need uint64) bool {
var st syscall.Statfs_t
if err := syscall.Statfs(dir, &st); err != nil { return false }
return uint64(st.Bavail)*uint64(st.Bsize) >= need
} Try / catch
if _, err := dechunker.WriteChunk(chunk); err != nil {
if strings.Contains(err.Error(), "failed to write decompressed data") {
// clean up partial temp file, free space or fix fs, restart chunked transfer from chunk 0
}
return err
} Prevention
- Monitor free space on the node's data directory before chunked uploads/restores
- Delete partial reassembly files after a failed transfer
- Alert on disk usage thresholds (e.g. 85%) in production
- Keep the dechunker temp dir on the same healthy volume as the data dir
When it happens
Trigger: Calling Dechunker.WriteChunk with a chunk whose decompression succeeds but whose destination file write fails: disk full, I/O error, file descriptor closed/invalid, or underlying storage failure during io.Copy(d.file, gzw).
Common situations: Uploading very large compressed blobs (backups, restores) that exceed available disk space on the node's temp/data directory; read-only or full filesystem; container disk quota exceeded mid-transfer.
Related errors
- failed to close file: %v
- short write
- failed to create gzip reader: %v
- failed to create dechunker manager: %s
- failed to read file %s: %w
AI-assisted analysis of rqlite/rqlite@7586a4d1bd (2026-09-03).
Data as JSON: /api/errors/8364a8adfc49b442.
Report an issue: GitHub.