{"record":{"id":"7c12e19d22039729","repo":"nats-io/nats-server","slug":"duplicate-call-to-create-subscription-for-service","errorCode":null,"errorMessage":"duplicate call to create subscription for service import","messagePattern":"duplicate call to create subscription for service import","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/accounts.go","lineNumber":2268,"sourceCode":"\tif c == nil {\n\t\treturn nil, fmt.Errorf(\"no internal account client\")\n\t}\n\n\treturn c.processSubEx([]byte(subject), nil, []byte(sid), cb, false, false, ri)\n}\n\n// This will add an account subscription that matches the \"from\" from a service import entry.\nfunc (a *Account) addServiceImportSub(si *serviceImport) error {\n\ta.mu.Lock()\n\tc := a.internalClient()\n\t// This will happen in parsing when the account has not been properly setup.\n\tif c == nil {\n\t\ta.mu.Unlock()\n\t\treturn nil\n\t}\n\tif si.sid != nil {\n\t\ta.mu.Unlock()\n\t\treturn fmt.Errorf(\"duplicate call to create subscription for service import\")\n\t}\n\ta.isid++\n\tsid := strconv.FormatUint(a.isid, 10)\n\tsi.sid = []byte(sid)\n\tsubject := si.from\n\ta.mu.Unlock()\n\n\tcb := func(sub *subscription, c *client, acc *Account, subject, reply string, msg []byte) {\n\t\tc.pa.delivered = c.processServiceImport(si, acc, msg)\n\t}\n\tsub, err := c.processSubEx([]byte(subject), nil, []byte(sid), cb, true, true, false)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Leafnodes introduce a new way to introduce messages into the system. Therefore forward import subscription\n\t// This is similar to what initLeafNodeSmapAndSendSubs does\n\t// TODO we need to consider performing this update as we get client subscriptions.\n\t//      This behavior would result in subscription propagation only where actually used.","sourceCodeStart":2250,"sourceCodeEnd":2286,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/accounts.go#L2250-L2286","documentation":"Returned by addServiceImportSub when the serviceImport entry already has a subscription id (si.sid != nil), meaning a subscription for this service import was already created and the duplicate creation attempt is rejected to prevent double-delivery.","triggerScenarios":"Invoking the internal subscription creation path twice for the same serviceImport entry, e.g. duplicate setup during import processing or re-registration without clearing sid.","commonSituations":"Race conditions or re-entrant account import updates processing the same import twice; manually calling internal setup helpers in tests.","solutions":["Do not call the internal subscribe helper twice for the same service import entry.","Clear/recreate the service import entry if a fresh subscription is required.","Check si.sid before requesting subscription creation."],"exampleFix":"// before\nacc.subscribeInternal(si, cb)\nacc.subscribeInternal(si, cb) // duplicate\n// after\nif si.sid == nil {\n    acc.subscribeInternal(si, cb)\n}","handlingStrategy":"validation","validationCode":"if si.sid != nil {\n    return errors.New(\"service import already subscribed\")\n}","typeGuard":null,"tryCatchPattern":"if err := setupServiceImportSubscription(acc, si, cb); err != nil {\n    if strings.Contains(err.Error(), \"duplicate call\") {\n        // skip; subscription already active\n    }\n}","preventionTips":["Guard internal subscription setup with a sid check","Avoid re-entrant import processing","Recreate import entries instead of re-subscribing"],"tags":["nats-server","service-import","duplicate-subscription"],"backgroundTag":"duplicate-internal-subscription","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}