{"record":{"id":"8ab83079bb3b2223","repo":"weaviate/weaviate","slug":"read-rq-mean","errorCode":null,"errorMessage":"read RQ mean","messagePattern":"read RQ mean","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"adapters/repos/db/vector/hnsw/compact/snapshot_reader.go","lineNumber":301,"sourceCode":"\t}\n\tif err := applyRQCenteredFlags(res.CompressionRQData(), flags); err != nil {\n\t\treturn err\n\t}\n\tvar meanLen uint32\n\tif err := binary.Read(reader, binary.LittleEndian, &meanLen); err != nil {\n\t\treturn errors.Wrap(err, \"read RQ mean length\")\n\t}\n\t// The mean always has exactly InputDim entries; validating before the\n\t// allocation stops a damaged snapshot from requesting an arbitrarily\n\t// large slice.\n\tif inputDim := res.CompressionRQData().InputDim; meanLen != inputDim {\n\t\treturn errors.Errorf(\"centered RQ mean length %d does not match input dimension %d\", meanLen, inputDim)\n\t}\n\tmean := make([]float32, meanLen)\n\tfor i := range mean {\n\t\tvar bits uint32\n\t\tif err := binary.Read(reader, binary.LittleEndian, &bits); err != nil {\n\t\t\treturn errors.Wrap(err, \"read RQ mean\")\n\t\t}\n\t\tmean[i] = math.Float32frombits(bits)\n\t}\n\tres.CompressionRQData().Mean = mean\n\treturn nil\n}\n\n// readPQData reads Product Quantization data from the reader.\nfunc (r *SnapshotReader) readPQData(reader io.Reader, res *ent.DeserializationResult) error {\n\tvar dims, ks, m uint16\n\tvar encoderType, dist uint8\n\tvar useBitsEncoding uint8\n\n\tif err := binary.Read(reader, binary.LittleEndian, &dims); err != nil {\n\t\treturn errors.Wrap(err, \"read PQ dimensions\")\n\t}\n\tif err := binary.Read(reader, binary.LittleEndian, &ks); err != nil {\n\t\treturn errors.Wrap(err, \"read PQ Ks\")","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/repos/db/vector/hnsw/compact/snapshot_reader.go#L283-L319","documentation":"This error is wrapped around a binary.Read failure while deserializing the centering mean vector of a centered-RQ (residual quantization) payload from an HNSW snapshot file. Each mean entry is a little-endian uint32 of float bits; if the underlying reader returns an error (almost always io.EOF/unexpected EOF), the mean vector cannot be reconstructed and snapshot deserialization aborts. It indicates the snapshot file ended (or the reader failed) mid-way through the mean section.","triggerScenarios":"Deserializing an HNSW snapshot whose compression type is SnapshotCompressionTypeRQCentered via SnapshotReader.readRQCenteredData (called from readCompressionData), when the reader is exhausted before meanLen float32 values can be read — i.e. truncated file, partially written/failed snapshot upload, or reading beyond the metadata section.","commonSituations":"Restoring a shard from a replica snapshot that was cut short by a crash or network interruption; copying snapshot files with rsync/scp before they finished flushing; mixing snapshot files from different Weaviate versions where the centered-RQ layout changed; a corrupted disk sector in the snapshot object on the backup target.","solutions":["Re-create the snapshot (re-export/re-upload the shard) and restore from the fresh, complete file; verify its byte size matches the source.","Checksum (e.g. sha256) the snapshot file against the source and re-transfer if it differs.","Confirm the snapshot was produced by a compatible Weaviate version and that the whole file (including the trailing mean section) was serialized, not just the header.","If truncation is recurring, check disk space and write-flush behavior on the node producing snapshots; a full disk mid-write yields truncated files."],"exampleFix":"// before: reading a locally truncated/partial snapshot stream\nf, _ := os.Open(\"shard-snapshot.bin\")\nr := compact.NewSnapshotReader(f)\nres, err := r.Do(context.Background(), shardName, className) // fails: read RQ mean: unexpected EOF\n\n// after: validate completeness (size/checksum) before deserializing\nwant, _ := sourceObject.Size() // e.g. from remote storage API\ngot, _ := os.Stat(\"shard-snapshot.bin\")\nif got.Size() != want {\n    return errors.New(\"snapshot incomplete, re-download before restoring\")\n}\nf, _ := os.Open(\"shard-snapshot.bin\")\nr := compact.NewSnapshotReader(f)\nres, err := r.Do(context.Background(), shardName, className)","handlingStrategy":"validation","validationCode":"info, err := os.Stat(snapshotPath)\nif err != nil { return err }\n// A centered-RQ snapshot must be at least large enough for the header + meanLen*4 bytes;\n// reject obviously short files before attempting deserialization.\nif info.Size() < minViableSnapshotBytes {\n    return fmt.Errorf(\"snapshot %s is %d bytes; expected >= %d — re-export before restore\", snapshotPath, info.Size(), minViableSnapshotBytes)\n}\nif sum := sha256File(snapshotPath); sum != expectedChecksum {\n    return fmt.Errorf(\"snapshot checksum mismatch: got %s, want %s\", sum, expectedChecksum)\n}","typeGuard":"func snapshotLooksComplete(info os.FileInfo, expectedSize int64) bool {\n    return info != nil && !info.IsDir() && info.Size() >= expectedSize\n}","tryCatchPattern":"res, err := snapshotReader.Do(ctx, shard, class)\nif err != nil {\n    var eof *fs.PathError\n    if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) || strings.Contains(err.Error(), \"read RQ mean\") {\n        return fmt.Errorf(\"snapshot truncated or corrupt (centered-RQ mean unreadable): %w — re-export the snapshot\", err)\n    }\n    return err\n}","preventionTips":["Always checksum (sha256) snapshot files at export time and verify at restore time.","Download snapshots to a temp file and atomically rename only after the transfer completes.","Monitor disk space on nodes producing snapshots; ENOSPC mid-write causes truncation.","Pin compatible Weaviate versions between snapshot producer and consumer."],"tags":["go","snapshot","deserialization","quantization","truncated-file"],"backgroundTag":"snapshot-file-truncated","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}