gofr-dev/gofr · error
create or update stream error
Error message
create or update stream error
What it means
errCreateOrUpdateStream (errors.go:19) is returned by StreamManager.CreateOrUpdateStream when the jetstream CreateOrUpdateStream API fails — neither creating nor updating the stream succeeded. Exercised by TestStreamManager_CreateOrUpdateStream_Error.
Source
Thrown at pkg/gofr/datasource/pubsub/nats/errors.go:19
package nats
import "errors"
var (
// Client Errors.
errServerNotProvided = errors.New("client server address not provided")
errSubjectsNotProvided = errors.New("subjects not provided")
errConsumerNotProvided = errors.New("consumer name not provided")
errConsumerCreationError = errors.New("consumer creation error")
errFailedToDeleteStream = errors.New("failed to delete stream")
errPublishError = errors.New("publish error")
errJetStreamNotConfigured = errors.New("jStream is not configured")
errJetStreamCreationFailed = errors.New("jStream creation failed")
errJetStream = errors.New("jStream error")
errCreateStream = errors.New("create stream error")
errDeleteStream = errors.New("delete stream error")
errGetStream = errors.New("get stream error")
errCreateOrUpdateStream = errors.New("create or update stream error")
errHandlerError = errors.New("handler error")
errConnectionError = errors.New("connection error")
errSubscriptionError = errors.New("subscription error")
)
View on GitHub (pinned to 187eb24962)
Solutions
- Inspect the wrapped NATS error — upsert failures usually name the conflicting field (retention/storage/discard policy).
- Match the existing stream's configuration (`nats stream info`) or delete and recreate the stream if reconfiguration is required.
- Validate subject patterns and reduce Replicas to what the account/cluster allows.
- Ensure only one provisioning path owns the stream config to avoid deployment races.
Example fix
// before: changing retention on an existing stream via upsert fails
err := sm.CreateOrUpdateStream(ctx, &jetstream.StreamConfig{Name: "ORDERS", Retention: jetstream.LimitsPolicy})
// after: match existing config or recreate
cfg, _ := js.Stream(ctx, "ORDERS")
_ = cfg // inspect existing settings; keep them consistent in StreamConfig Defensive patterns
Strategy: validation
Validate before calling
existing, err := js.Stream(ctx, cfg.Name)
if err == nil {
if existing.CachedInfo().Config.Retention != cfg.Retention {
return fmt.Errorf("stream %q exists with different retention; manual migration required", cfg.Name)
}
} Try / catch
if err := sm.CreateOrUpdateStream(ctx, cfg); err != nil {
return fmt.Errorf("upsert stream %s failed: %w (check conflicting config with `nats stream info %s`)", cfg.Name, err, cfg.Name)
} Prevention
- Fetch the existing stream config and diff it before upserting.
- Never change immutable fields (storage, retention) via upsert; plan a migration.
- Keep replicas within account/cluster limits.
- Use a single owner for stream definitions to avoid deploy races.
When it happens
Trigger: Calling CreateOrUpdateStream with a StreamConfig that conflicts with an existing stream's immutable fields, invalid subjects, resource limits, or no JetStream connection.
Common situations: Changing retention or storage on an existing stream via upsert; replicas requested above account limits; multiple deploy pipelines racing to define the same stream differently.
Related errors
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/b33b132bc7069d0a.
Report an issue: GitHub.