nats-io/nats-server · error

store is read-only

Error message

store is read-only

What it means

DirJWTStore.delete guard: the store was opened in read-only mode (store.readonly), so delete operations are refused to keep the on-disk store untouched.

Source

Thrown at server/dirstore.go:454

			i := store.expiration.lru.Front().Value.(*jwtItem)
			if err := os.Remove(store.pathForKey(i.publicKey)); err != nil {
				return false, err
			} else {
				store.expiration.unTrack(i.publicKey)
			}
		}
	}
	if err := os.WriteFile(path, []byte(theJWT), defaultFilePerms); err != nil {
		return false, err
	} else if store.expiration != nil {
		store.expiration.track(publicKey, newHash, theJWT)
	}
	return true, nil
}

func (store *DirJWTStore) delete(publicKey string) error {
	if store.readonly {
		return fmt.Errorf("store is read-only")
	} else if store.deleteType == NoDelete {
		return fmt.Errorf("store is not set up to for delete")
	}
	store.Lock()
	defer store.Unlock()
	name := store.pathForKey(publicKey)
	if store.deleteType == RenameDeleted {
		if err := os.Rename(name, name+".deleted"); err != nil {
			if os.IsNotExist(err) {
				return nil
			}
			return err
		}
	} else if err := os.Remove(name); err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return err

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Re-open the store without the read-only flag
  2. Use a writable directory for stores that need deletes
  3. Perform maintenance on the underlying files out-of-band
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/dirstore.go:454 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/e31ebab9d4a00bea. Report an issue: GitHub.