thanos-io/thanos · error

sync temporary dir file

Error message

sync temporary dir file

What it means

Flush fails when df.Sync() cannot flush the temporary directory's directory entry to stable storage. Persisting directory entries (so renamed chunk/index files survive crashes) is required for durable block writes; failure here aborts publication of the block.

Solutions

  1. Verify disk health and free space on the target volume.
  2. Avoid storing block dirs on filesystems that reject directory fsync (use local/ext4/xfs).
  3. Retry Flush after transient EIO; investigate dmesg for device errors.
  4. Delete the incomplete tmp dir and re-create the block.

Example fix

// before (unsupported FS)
$ df -T /data  ->  nfs
// after: migrate block storage to a local filesystem
$ df -T /data  ->  ext4
Defensive patterns

Strategy: retry

Validate before calling

if free, err := diskFree(bdir); err == nil && free < minRequiredBytes {
    return fmt.Errorf("low disk space before flush: %d bytes", free)
}

Try / catch

var lastErr error
for i := 0; i < 3; i++ {
    if _, err := d.Flush(ctx); err != nil {
        if strings.Contains(err.Error(), "sync temporary dir file") {
            lastErr = err
            time.Sleep(backoff(i))
            continue
        }
        return err
    }
    return nil
}
return lastErr

Prevention

When it happens

Trigger: Calling fsync on the opened temp dir failing — usually ENOSPC, EIO, or unsupported fsync-on-directory on exotic filesystems, or the dir having been closed/invalidated.

Common situations: Disk full or failing storage device; network filesystems (some NFS/S3-FUSE mounts) that don't support directory fsync; kernel/device errors under heavy IO load.

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/3c900551d0c48482. Report an issue: GitHub.

Appendix: source

Thrown at pkg/block/writer.go:123

		if err != nil {
			err = tsdb_errors.NewMulti(err, tsdb_errors.CloseAll(d.closers)).Err()
			if err := os.RemoveAll(d.bTmp); err != nil {
				level.Error(d.logger).Log("msg", "removed tmp folder failed after block(s) write", "err", err.Error())
			}
		}
	}()
	df, err := fileutil.OpenDir(d.bTmp)
	if err != nil {
		return tsdb.BlockStats{}, errors.Wrap(err, "open temporary block dir")
	}
	defer func() {
		if df != nil {
			err = tsdb_errors.NewMulti(err, df.Close()).Err()
		}
	}()

	if err := df.Sync(); err != nil {
		return tsdb.BlockStats{}, errors.Wrap(err, "sync temporary dir file")
	}

	// Close temp dir before rename block dir (for windows platform).
	if err = df.Close(); err != nil {
		return tsdb.BlockStats{}, errors.Wrap(err, "close temporary dir")
	}
	df = nil

	if err := tsdb_errors.CloseAll(d.closers); err != nil {
		d.closers = nil
		return tsdb.BlockStats{}, err
	}
	d.closers = nil

	// Block files successfully written, make them visible by moving files from tmp dir.
	if err := fileutil.Replace(filepath.Join(d.bTmp, IndexFilename), filepath.Join(d.bDir, IndexFilename)); err != nil {
		return tsdb.BlockStats{}, errors.Wrap(err, "replace index file")
	}

View on GitHub (pinned to 35b8b99117)