thanos-io/thanos · error

sync dir

Error message

sync dir

What it means

After creating the FileWriter for the index-header cache file, newBinaryWriter calls df.Sync() on the opened parent directory handle to durably persist the directory entry (the new file's existence). This error wraps the fsync failure on that directory, meaning the OS could not flush the directory metadata to disk.

Solutions

  1. Move the cache directory onto a local filesystem that supports directory fsync (ext4/xfs).
  2. Check dmesg / disk health for underlying I/O errors and fix hardware issues.
  3. If on a network FS that returns EINVAL for dir fsync, reconfigure the storage or patch to skip dir sync there.
  4. Retry WriteBinary after transient I/O errors.

Example fix

// before
if err := df.Sync(); err != nil {
    return nil, errors.Wrap(err, "sync dir")
}
// after
if err := df.Sync(); err != nil {
    if errors.Is(err, syscall.EINVAL) {
        logger.Warn("directory fsync unsupported on this filesystem; skipping")
    } else {
        return nil, errors.Wrap(err, "sync dir")
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

_, err := WriteBinary(ctx, bkt, id, cachePath, metrics.DownloadDuration)
if err != nil {
    if errors.Is(err, syscall.EINVAL) || errors.Is(err, syscall.ENOTSUP) {
        // filesystem does not support dir fsync; fall back to memory reader
        return NewBinaryReader(ctx, logger, bkt, "", id, sampling, metrics)
    }
    return errors.Wrap(err, "index header generation")
}

Prevention

When it happens

Trigger: df.Sync() (directory fsync) returns an error inside newBinaryWriter when cacheFilename != '': disk I/O error, filesystem that does not support directory fsync (some network/FUSE filesystems return EINVAL), or the directory handle became invalid.

Common situations: Storing the block cache directory on NFS/CIFS/FUSE mounts that reject fsync on directories; failing disk or full/failing device; container with restricted syscall support.

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/75179ac84a1d7b07. Report an issue: GitHub.

Appendix: source

Thrown at pkg/block/indexheader/binary_reader.go:320

			df, err = fileutil.OpenDir(dir)
		}
		if err != nil {
			return nil, err
		}

		defer runutil.CloseWithErrCapture(&err, df, "dir close")

		if err := os.RemoveAll(cacheFilename); err != nil {
			return nil, errors.Wrap(err, "remove any existing index at path")
		}

		var fileWriter *FileWriter
		fileWriter, err = NewFileWriter(cacheFilename, len(buf))
		if err != nil {
			return nil, err
		}
		if err := df.Sync(); err != nil {
			return nil, errors.Wrap(err, "sync dir")
		}
		binWriter = fileWriter
	} else {
		binWriter = NewMemoryWriter(id, len(buf))
	}

	w = &binaryWriter{
		writer: binWriter,

		// Reusable memory.
		buf:   encoding.Encbuf{B: buf},
		crc32: newCRC32(),
	}

	w.buf.Reset()
	w.buf.PutBE32(MagicIndex)
	w.buf.PutByte(BinaryFormatV1)

View on GitHub (pinned to 35b8b99117)