{"record":{"id":"f552054e6e2de441","repo":"weaviate/weaviate","slug":"store-is-read-only","errorCode":null,"errorMessage":"store is read-only","messagePattern":"store is read-only","errorType":"error_code","errorClass":null,"httpStatus":403,"severity":"error","filePath":"entities/storagestate/status.go","lineNumber":33,"sourceCode":"\t\"errors\"\n\t\"fmt\"\n)\n\nconst (\n\tStatusReadOnly    Status = \"READONLY\"\n\tStatusIndexing    Status = \"INDEXING\"\n\tStatusLoading     Status = \"LOADING\"\n\tStatusLazyLoading Status = \"LAZY_LOADING\"\n\tStatusReady       Status = \"READY\"\n\tStatusShutdown    Status = \"SHUTDOWN\"\n)\n\nvar ErrStatusReadOnlyWithReason = func(reason string) error {\n\treturn fmt.Errorf(\"store is read-only due to: %v\", reason)\n}\n\nvar (\n\tErrStatusReadOnly = errors.New(\"store is read-only\")\n\tErrInvalidStatus  = errors.New(\"invalid storage status\")\n)\n\ntype Status string\n\nfunc (s Status) String() string {\n\treturn string(s)\n}\n\nfunc ValidateStatus(in string) (status Status, err error) {\n\tswitch in {\n\tcase string(StatusReadOnly):\n\t\tstatus = StatusReadOnly\n\tcase string(StatusIndexing):\n\t\tstatus = StatusIndexing\n\tcase string(StatusReady):\n\t\tstatus = StatusReady\n\tcase string(StatusShutdown):","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/entities/storagestate/status.go#L15-L51","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Stop issuing writes once the store is read-only; check bucket/storage status before writes if a shutdown may be in progress","Retry the operation on another node (in a cluster) or after restarting the process","Check earlier logs for ErrStatusReadOnlyWithReason to find why the store went read-only (often an underlying disk error)","Treat this via errors.Is(err, storagestate.ErrStatusReadOnly) and surface 'node unavailable' to clients rather than retrying against the same bucket"],"exampleFix":"if err := b.FlushMemtable(); err != nil {\n    if errors.Is(err, storagestate.ErrStatusReadOnly) {\n        return ErrUnavailable // do not retry locally\n    }\n    return err\n}","handlingStrategy":"type-guard","validationCode":"if b.Status() == storagestate.StatusReadOnly {\n    return storagestate.ErrStatusReadOnly\n}","typeGuard":"func isReadOnly(err error) bool { return errors.Is(err, storagestate.ErrStatusReadOnly) }","tryCatchPattern":"if err := doWrite(); err != nil {\n    if errors.Is(err, storagestate.ErrStatusReadOnly) {\n        // route to another node / stop writes\n        return ErrUnavailable\n    }\n    return err\n}","preventionTips":["Check bucket status before writes during shutdown windows","Monitor logs for 'store is read-only due to' to catch underlying IO problems early","Use errors.Is, not string comparison, to detect this sentinel","Gracefully drain writers before calling Shutdown"],"tags":["storage","lsmkv","read-only","shutdown"],"backgroundTag":"store-read-only","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"}