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.

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.

Appendix: 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)