weaviate/weaviate · error

read level

Error message

read level

What it means

Thrown in SnapshotReader.readMetadata when binary.Read fails to read the 2-byte HNSW graph level (uint16, little-endian) from the snapshot's metadata buffer. The metadata blob itself was already checksum-verified, so reaching this point with too few bytes means the metadata was written shorter than the reader expects — typically a truncated or corrupt snapshot file, or a version/format mismatch. The wrapped io.EOF / ErrUnexpectedEOF propagates up and aborts deserialization of the whole HNSW snapshot.

Source

Thrown at adapters/repos/db/vector/hnsw/compact/snapshot_reader.go:203

	_, _ = hasher.Write(metadata)
	if hasher.Sum32() != checksum {
		return 0, fmt.Errorf("metadata checksum mismatch")
	}

	// Parse metadata
	metaReader := bytes.NewReader(metadata)

	// Entrypoint
	var entrypoint uint64
	if err := binary.Read(metaReader, binary.LittleEndian, &entrypoint); err != nil {
		return 0, errors.Wrap(err, "read entrypoint")
	}
	res.Graph.Entrypoint = entrypoint

	// Level
	var level uint16
	if err := binary.Read(metaReader, binary.LittleEndian, &level); err != nil {
		return 0, errors.Wrap(err, "read level")
	}
	res.Graph.Level = level

	// isCompressed
	var isCompressed uint8
	if err := binary.Read(metaReader, binary.LittleEndian, &isCompressed); err != nil {
		return 0, errors.Wrap(err, "read isCompressed")
	}
	res.SetCompressed(isCompressed != 0)

	if res.Compressed() {
		if err := r.readCompressionData(metaReader, res); err != nil {
			return 0, errors.Wrap(err, "read compression data")
		}
	}

	// isEncoded (Muvera)
	var isEncoded uint8

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Delete the corrupted snapshot file (and its condensor/tmp artifacts) and restart Weaviate so the snapshot regenerates from the commit log or via a new compaction cycle.
  2. Verify disk health and free space on the volume holding the shard data; check dmesg/filesystem logs for I/O errors around the time it was written.
  3. Check that the Weaviate version that produced the shard matches the one reading it; restore shards only into compatible versions.
  4. If corruption recurs, re-import the collection from a backup taken before the corruption.

Example fix

// operator fix, no code change
// before (corrupt snapshot present)
ls persistence-dir/<shard>/vector_index/hnsw.snapshot  # partially written
// after
rm persistence-dir/<shard>/vector_index/hnsw.snapshot* && restart weaviate
Defensive patterns

Strategy: validation

Validate before calling

fi, err := os.Stat(snapshotPath); if err != nil || fi.Size() < 32 { /* snapshot missing/truncated -> regenerate before loading */ }

Try / catch

if err := reader.Read(f); err != nil { if strings.Contains(err.Error(), "read level") || errors.Is(err, io.ErrUnexpectedEOF) { os.Remove(snapshotPath); /* trigger recompaction/rebuild */ } return err }

Prevention

When it happens

Trigger: Calling SnapshotReader.Read on a snapshot file whose metadata section ends before the level field: the file was truncated on disk, the metadata buffer is corrupt despite a passing checksum, or the snapshot was produced by a writer whose metadata layout differs from this reader's expectations.

Common situations: Disk full or node crash while the compaction snapshot was being written; restoring/copying shard files manually and truncating the .snapshot file; different Weaviate versions involved in backup restore where the metadata field order changed; corrupted persistent storage.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/859485dee07b1a6a. Report an issue: GitHub.