weaviate/weaviate · error

store is read-only

Error message

store is read-only

What it means

ErrStatusReadOnly is the sentinel error signaling that an LSMkv bucket/store has transitioned to read-only (e.g. during shutdown, or after a critical failure like a corrupted compressed vector). Any mutating operation (put, flush, etc.) performed on a read-only bucket returns this error so writes are never silently dropped.

Source

Thrown at entities/storagestate/status.go:33

	"errors"
	"fmt"
)

const (
	StatusReadOnly    Status = "READONLY"
	StatusIndexing    Status = "INDEXING"
	StatusLoading     Status = "LOADING"
	StatusLazyLoading Status = "LAZY_LOADING"
	StatusReady       Status = "READY"
	StatusShutdown    Status = "SHUTDOWN"
)

var ErrStatusReadOnlyWithReason = func(reason string) error {
	return fmt.Errorf("store is read-only due to: %v", reason)
}

var (
	ErrStatusReadOnly = errors.New("store is read-only")
	ErrInvalidStatus  = errors.New("invalid storage status")
)

type Status string

func (s Status) String() string {
	return string(s)
}

func ValidateStatus(in string) (status Status, err error) {
	switch in {
	case string(StatusReadOnly):
		status = StatusReadOnly
	case string(StatusIndexing):
		status = StatusIndexing
	case string(StatusReady):
		status = StatusReady
	case string(StatusShutdown):

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Stop issuing writes once the store is read-only; check bucket/storage status before writes if a shutdown may be in progress
  2. Retry the operation on another node (in a cluster) or after restarting the process
  3. Check earlier logs for ErrStatusReadOnlyWithReason to find why the store went read-only (often an underlying disk error)
  4. Treat this via errors.Is(err, storagestate.ErrStatusReadOnly) and surface 'node unavailable' to clients rather than retrying against the same bucket

Example fix

if err := b.FlushMemtable(); err != nil {
    if errors.Is(err, storagestate.ErrStatusReadOnly) {
        return ErrUnavailable // do not retry locally
    }
    return err
}
Defensive patterns

Strategy: type-guard

Validate before calling

if b.Status() == storagestate.StatusReadOnly {
    return storagestate.ErrStatusReadOnly
}

Type guard

func isReadOnly(err error) bool { return errors.Is(err, storagestate.ErrStatusReadOnly) }

Try / catch

if err := doWrite(); err != nil {
    if errors.Is(err, storagestate.ErrStatusReadOnly) {
        // route to another node / stop writes
        return ErrUnavailable
    }
    return err
}

Prevention

When it happens

Trigger: Calling bucket write operations such as Put or FlushMemtable after the bucket status was set to storagestate.StatusReadOnly — typically during graceful shutdown, or after the store flipped itself read-only following a disk/IO failure (e.g. recoverCompressedVector detecting a genuine IO error).

Common situations: Requests racing a node shutdown; background compaction/flush during shutdown; application keeps writing after an earlier operation already failed and flipped the bucket read-only.

Related errors


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