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

  1. Inspect the wrapped NATS error — upsert failures usually name the conflicting field (retention/storage/discard policy).
  2. Match the existing stream's configuration (`nats stream info`) or delete and recreate the stream if reconfiguration is required.
  3. Validate subject patterns and reduce Replicas to what the account/cluster allows.
  4. 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

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.