thanos-io/thanos · error

write

Error message

write

What it means

After compaction produces the merged series set, WriteSeries writes the result to the destination block writer via w.write(); failure is wrapped as "write". This is a failure while actually materializing the output block (symbols, series, chunks).

Solutions

  1. Check free disk space on the volume receiving the new block and clean up if full
  2. Inspect the wrapped inner error for the specific file or chunk encoding that failed
  3. Verify the destination block.Writer was correctly opened (TempDir/ directory writable)
  4. Rerun compaction; if it fails repeatedly on the same chunk, investigate the source chunk data
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure destination has free space before compaction
if err := checkFreeSpace(destDir, estimatedSize); err != nil {
    return err
}

Try / catch

if err := comp.WriteSeries(ctx, readers, sWriter, progress); err != nil {
    if strings.Contains(err.Error(), "write") {
        logger.Error("failed writing compacted block", "err", err)
        // clean partial temp dir of destination writer
    }
    return err
}

Prevention

When it happens

Trigger: w.write fails: destination writer (block.Writer) errors — disk full, I/O error writing segment/symbol/index files, append/encoding failures on individual chunks, or progress-reporting/abort checks inside write.

Common situations: Out of disk space on the data volume during compaction; failing disk; output writer pointing to an invalid or closed sink; unencodable chunk data produced by modifiers.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/d2e8f2171659359e. Report an issue: GitHub.

Appendix: source

Thrown at pkg/compactv2/compactor.go:149

			}

			s := set.At()
			iter := s.Iterator(nil)
			for iter.Next() {
			}
			if err := iter.Err(); err != nil {
				level.Error(w.logger).Log("msg", "error while iterating over chunks", "series", s.Labels(), "err", err)
			}
			p.SeriesProcessed()
		}
		if err := set.Err(); err != nil {
			level.Error(w.logger).Log("msg", "error while iterating over set", "err", err)
		}
		return nil
	}

	if err := w.write(ctx, symbols, set, sWriter, p); err != nil {
		return errors.Wrap(err, "write")
	}
	return nil
}

// compactSeries compacts blocks' series into symbols and one ChunkSeriesSet with lazy populating chunks.
func compactSeries(ctx context.Context, sReaders ...seriesReader) (symbols index.StringIter, set storage.ChunkSeriesSet, _ error) {
	if len(sReaders) == 0 {
		return nil, nil, errors.New("cannot populate block from no readers")
	}

	var sets []storage.ChunkSeriesSet
	for i, r := range sReaders {
		select {
		case <-ctx.Done():
			return nil, nil, ctx.Err()
		default:
		}

View on GitHub (pinned to 35b8b99117)