diff --git a/tsdb/index/index.go b/tsdb/index/index.go index 1ddcac9501..8a76770821 100644 --- a/tsdb/index/index.go +++ b/tsdb/index/index.go @@ -17,6 +17,7 @@ import ( "bufio" "context" "encoding/binary" + "errors" "fmt" "hash" "hash/crc32" @@ -94,6 +95,13 @@ func (s indexWriterStage) String() string { return "" } +// ErrPostingsOffsetTableTooLarge is returned when the postings offset table length +// would exceed 4 bytes (table would exceed the 4GB limit). +var ErrPostingsOffsetTableTooLarge = errors.New("length size exceeds 4 bytes") + +// ErrIndexExceeds64GiB is returned when the index file would exceed the 64GiB limit. +var ErrIndexExceeds64GiB = errors.New("exceeding max size of 64GiB") + // The table gets initialized with sync.Once but may still cause a race // with any other use of the crc32 package anywhere. Thus we initialize it // before. @@ -303,7 +311,7 @@ func (fw *FileWriter) Write(bufs ...[]byte) error { // Once we move to compressed/varint representations in those areas, this limitation // can be lifted. if fw.pos > 16*math.MaxUint32 { - return fmt.Errorf("%q exceeding max size of 64GiB", fw.name) + return fmt.Errorf("%q %w", fw.name, ErrIndexExceeds64GiB) } } return nil @@ -660,7 +668,7 @@ func (w *Writer) writeLengthAndHash(startPos uint64) error { w.buf1.Reset() l := w.f.pos - startPos - 4 if l > math.MaxUint32 { - return fmt.Errorf("length size exceeds 4 bytes: %d", l) + return fmt.Errorf("%w: %d", ErrPostingsOffsetTableTooLarge, l) } w.buf1.PutBE32int(int(l)) if err := w.writeAt(w.buf1.Get(), startPos); err != nil {