nats-io/nats-server · warning

stream import already exists

Error message

stream import already exists

What it means

ErrStreamImportDuplicate is returned when a stream import is a duplicate of one that already exists on the account — isStreamImportDuplicate detects an existing import from the same account with the same subject (from), and the server refuses to add it twice.

Source

Thrown at server/errors.go:144

	ErrAccountExpired = errors.New("account expired")

	// ErrNoAccountResolver is returned when we attempt an update but do not have an account resolver.
	ErrNoAccountResolver = errors.New("account resolver missing")

	// ErrAccountResolverUpdateTooSoon is returned when we attempt an update too soon to last request.
	ErrAccountResolverUpdateTooSoon = errors.New("account resolver update too soon")

	// ErrAccountResolverSameClaims is returned when same claims have been fetched.
	ErrAccountResolverSameClaims = errors.New("account resolver no new claims")

	// ErrStreamImportAuthorization is returned when a stream import is not authorized.
	ErrStreamImportAuthorization = errors.New("stream import not authorized")

	// ErrStreamImportBadPrefix is returned when a stream import prefix contains wildcards.
	ErrStreamImportBadPrefix = errors.New("stream import prefix can not contain wildcard tokens")

	// ErrStreamImportDuplicate is returned when a stream import is a duplicate of one that already exists.
	ErrStreamImportDuplicate = errors.New("stream import already exists")

	// ErrServiceImportAuthorization is returned when a service import is not authorized.
	ErrServiceImportAuthorization = errors.New("service import not authorized")

	// ErrImportFormsCycle is returned when an import would form a cycle.
	ErrImportFormsCycle = errors.New("import forms a cycle")

	// ErrCycleSearchDepth is returned when we have exceeded our maximum search depth..
	ErrCycleSearchDepth = errors.New("search cycle depth exhausted")

	// ErrClientOrRouteConnectedToGatewayPort represents an error condition when
	// a client or route attempted to connect to the Gateway port.
	ErrClientOrRouteConnectedToGatewayPort = errors.New("attempted to connect to gateway port")

	// ErrWrongGateway represents an error condition when a server receives a connect
	// request from a remote Gateway with a destination name that does not match the server's
	// Gateway's name.
	ErrWrongGateway = errors.New("wrong gateway")

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Check whether the import already exists (iterate acc.streamImports or track in app state) before calling AddStreamImport
  2. Treat ErrStreamImportDuplicate as a success case (idempotent import) in setup/reload code
  3. Remove the existing import first (RemoveStreamImport) if the intent is to replace it, then re-add
  4. Deduplicate import definitions across config files/claims before applying them

Example fix

// before
importAcc.AddStreamImport(fooAcc, "test", "") // second time -> ErrStreamImportDuplicate
// after
if err := importAcc.AddStreamImport(fooAcc, "test", ""); err != nil && !errors.Is(err, ErrStreamImportDuplicate) {
	return err // duplicates are tolerated as idempotent
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check existing imports before adding
for _, im := range acc.streamImports {
	if im.fr == fromAccount && im.to == fromSubject { return nil /* already imported */ }
}

Type guard

func hasStreamImport(acc *Account, from *Account, subject string) bool {
	acc.mu.RLock(); defer acc.mu.RUnlock()
	for _, im := range acc.streamImports {
		if im.fr == from && im.to.Subject == subject { return true }
	}
	return false
}

Try / catch

if err := acc.AddStreamImport(fromAcc, subject, tok); err != nil {
	if errors.Is(err, ErrStreamImportDuplicate) { return nil } // idempotent re-add
}

Prevention

When it happens

Trigger: Calling AddStreamImport with the same (from account, from subject) pair that is already registered (accounts.go:2784), e.g. re-adding import "test" from fooAcc as in TestMultipleStreamImportsWithSameSubject / accounts_test.go:2676 after a prior import was allowed.

Common situations: Idempotency assumptions — code that adds imports on every config reload without checking existence; retries after a partial failure re-adding the import; multiple config sources defining the same import; tests asserting duplicate detection.

Related errors


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