nats-io/nats-server · error
service import not authorized
Error message
service import not authorized
What it means
ErrServiceImportAuthorization indicates a message could not be routed to a subject because the destination account has not authorized the source account to use its service export/import mapping. In NATS account-based authorization, a service import is only usable if the destination account's export (or explicit placement rules) permits the publishing account, including any token claims (imClaim) required by the export. The server returns this sentinel from checkServiceImportAuthorized during routing in server/accounts.go:1681 when that authorization check fails.
Source
Thrown at server/errors.go:147
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")
// ErrGatewayNameHasSpaces signals that the gateway name contains spaces, which is not allowed.
ErrGatewayNameHasSpaces = errors.New("gateway name cannot contain spaces")View on GitHub (pinned to 3a66a489d2)
Solutions
- Add or correct the service export on the destination account so its subject list includes the subject being imported.
- If the export is token/restriction-based, supply the correct authorization token in the subject or update the account JWT to permit the importing account.
- Push updated account JWTs to all servers (nsc push / resolver refresh) so stale authorization data is refreshed.
- Verify subject overlap between the export and import (wildcards must align) with `nats account` tooling.
Example fix
// before: account B has no export, account A imports
// {"imports":[{"type":"service","account":"B","subject":"svc.help"}]}
// after: add matching export in account B's JWT
// {"exports":[{"type":"service","subject":"svc.help","accounts":["A"]}]} Defensive patterns
Strategy: validation
Validate before calling
// Before publishing to an imported service, verify the import exists and is authorized
// via the account's imports and, where applicable, include the required export token in the subject:
// subject := "svc.help"
// if tokenRequired { subject = "svc.help." + token }
// Use `nats account report imports` / `nsc` to confirm a matching service export exists on the target account. Try / catch
if err := doRequest(); err != nil {
if errors.Is(err, ErrServiceImportAuthorization) {
// surface config guidance: check export on destination account / token claim
}
} Prevention
- Keep export and import subject lists in the same IaC change so they never drift.
- Use `nats account report` (or `nsc`) to validate export/import pairing before deploy.
- When exports are restricted, always inject the authorization token into the subject.
- Push account JWT updates to all servers before switching traffic.
When it happens
Trigger: Publishing or sending a service request to a subject that maps to another account's service import when the target account has not exported the subject for the source account; an export exists but is restricted (export placement/token) and the request lacks the required claim (imClaim); using an internal route bypassed by the `!internal` check fails for normal client traffic.
Common situations: Operator added a service import to account A but forgot a matching export (or the export's allow/deny lists) on account B; JWT account claims updated on the resolver but the importing server has stale account claims; missing authorization token in the subject when the export requires one.
Related errors
- import forms a cycle
- stream import not authorized
- account jwt not found
- auth callout violation: auth callout response is not for exp
- auth callout violation: auth callout response is not for ser
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/5a8cc9c0331fe183.
Report an issue: GitHub.