nats-io/nats-server · error
fileStore requires file storage type in config
Error message
fileStore requires file storage type in config
What it means
The JetStream file store constructor validates that the stream's storage type is FileStorage before creating a file-backed stream store. This error means a StreamConfig was passed with a different Storage value (e.g. MemoryStorage) while the fileStore implementation was selected. It is a config/implementation mismatch guard in newFileStoreWithCreatedAndMode (server/filestore.go:417).
Source
Thrown at server/filestore.go:417
// Above this number of subjects, index.db may not be written regularly anymore, and
// certain psim optimisations may not be used.
highCardinalityThreshold = 1_000_000
)
func newFileStore(fcfg FileStoreConfig, cfg StreamConfig) (*fileStore, error) {
return newFileStoreWithCreated(fcfg, cfg, time.Now().UTC(), nil, nil)
}
func newFileStoreWithCreated(fcfg FileStoreConfig, cfg StreamConfig, created time.Time, prf, oldprf keyGen) (fs *fileStore, err error) {
return newFileStoreWithCreatedAndMode(fcfg, cfg, created, prf, oldprf, false)
}
func newFileStoreWithCreatedAndMode(fcfg FileStoreConfig, cfg StreamConfig, created time.Time, prf, oldprf keyGen, recovering bool) (fs *fileStore, err error) {
if cfg.Name == _EMPTY_ {
return nil, fmt.Errorf("name required")
}
if cfg.Storage != FileStorage {
return nil, fmt.Errorf("fileStore requires file storage type in config")
}
// Default values.
if fcfg.BlockSize == 0 {
fcfg.BlockSize = dynBlkSize(cfg.Retention, cfg.MaxBytes, prf != nil)
}
if fcfg.BlockSize > maxBlockSize {
return nil, fmt.Errorf("filestore max block size is %s", friendlyBytes(maxBlockSize))
}
if fcfg.CacheExpire == 0 {
fcfg.CacheExpire = defaultCacheBufferExpiration
}
if fcfg.SubjectStateExpire == 0 {
fcfg.SubjectStateExpire = defaultFssExpiration
}
if fcfg.SyncInterval == 0 {
fcfg.SyncInterval = defaultSyncInterval
}
dios := fcfg.srv.diskIOSemaphore()View on GitHub (pinned to 3a66a489d2)
Solutions
- Set Storage: FileStorage in the StreamConfig before creating the stream
- If the stream should be memory-backed, use the memory store implementation instead of the file store
- Validate the config with a pre-check before calling the API
Example fix
// before
cfg := nats.StreamConfig{Name: "ORDERS", Storage: nats.MemoryStorage}
fs, err := newFileStoreWithCreatedAndMode(fcfg, cfg, time.Now(), nil, nil, false)
// after
cfg := nats.StreamConfig{Name: "ORDERS", Storage: nats.FileStorage}
fs, err := newFileStoreWithCreatedAndMode(fcfg, cfg, time.Now(), nil, nil, false) Defensive patterns
Strategy: validation
Validate before calling
func validFileStorage(cfg nats.StreamConfig) error {
if cfg.Storage != nats.FileStorage {
return fmt.Errorf("stream %q: got storage %v, want FileStorage", cfg.Name, cfg.Storage)
}
return nil
} Prevention
- Always set Storage explicitly in StreamConfig; never rely on zero values
- Run config validation before store creation
- Keep one config-building helper per storage backend
When it happens
Trigger: Calling file store creation (directly or via a stream restore/template) with StreamConfig.Storage set to MemoryStorage or any value other than FileStorage, while fileStore is the chosen implementation.
Common situations: Stream configs loaded from JSON where the storage field is missing or defaulted to memory; code that switches storage backends but reuses the file store constructor; restoring a snapshot into a memory-configured stream.
Related errors
- filestore max block size is %s
- could not create hash: %v
- failed to compress block: %w
- failed to write to temporary file: %w
- short write to temporary file (%d != %d)
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/9f003a9e7469e2da.
Report an issue: GitHub.