{"record":{"id":"73033b034a5c5916","repo":"ginuerzh/gost","slug":"obfs4-context-already-inited","errorCode":null,"errorMessage":"obfs4 context already inited","messagePattern":"obfs4 context already inited","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"obfs.go","lineNumber":680,"sourceCode":"\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\ntype obfs4Context struct {\n\tcf    base.ClientFactory\n\tcargs interface{} // type obfs4ClientArgs\n\tsf    base.ServerFactory\n\tsargs *pt.Args\n}\n\nvar obfs4Map = make(map[string]obfs4Context)\n\n// Obfs4Init initializes the obfs client or server based on isServeNode\nfunc Obfs4Init(node Node, isServeNode bool) error {\n\tif _, ok := obfs4Map[node.Addr]; ok {\n\t\treturn fmt.Errorf(\"obfs4 context already inited\")\n\t}\n\n\tt := new(obfs4.Transport)\n\n\tstateDir := node.Values.Get(\"state-dir\")\n\tif stateDir == \"\" {\n\t\tstateDir = \".\"\n\t}\n\n\tptArgs := pt.Args(node.Values)\n\n\tif !isServeNode {\n\t\tcf, err := t.ClientFactory(stateDir)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcargs, err := cf.ParseArgs(&ptArgs)","sourceCodeStart":662,"sourceCodeEnd":698,"githubUrl":"https://github.com/ginuerzh/gost/blob/a33fdbf4c98034f4bfeeaea9868909822b9c526d/obfs.go#L662-L698","documentation":"Obfs4Init keeps one obfs4Context per node address in a package-level map. Calling Obfs4Init twice for the same node address (without removing the entry) returns this error because re-initializing would overwrite live crypto state.","triggerScenarios":"Calling Obfs4Init(node, isServeNode) when obfs4Map already contains an entry for node.Addr — e.g. service restart within the same process, config reload, or two listeners/dialers sharing one node address.","commonSituations":"Hot-reloading gost config where obfs nodes are re-initialized without cleanup; running both client and server obfs on the same address in one process; double-start of a service due to supervisor misconfiguration.","solutions":["Call Obfs4Init only once per node address per process lifetime; guard with the same existence check the library uses.","If a re-init is intentional, remove the old entry from obfs4Map (or restart the process) before calling Obfs4Init again.","Use distinct node addresses for separate obfs contexts (client vs server)."],"exampleFix":"// before\nObfs4Init(node, true) // second call on reload panics with this error\n// after\nif _, err := obfs4GetContext(node.Addr); err != nil {\n    Obfs4Init(node, true)\n}","handlingStrategy":"validation","validationCode":"// guard your own init path\nvar inited = map[string]bool{}\nfunc ensureObfsInit(node Node, serve bool) error {\n    if inited[node.Addr] { return nil }\n    if err := Obfs4Init(node, serve); err != nil { return err }\n    inited[node.Addr] = true\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := Obfs4Init(node, true); err != nil {\n    if strings.Contains(err.Error(), \"already inited\") {\n        return nil // idempotent no-op\n    }\n    return err\n}","preventionTips":["Init each obfs4 address exactly once per process","Track init state on config reload","Use unique addresses per context"],"tags":["obfs4","initialization","duplicate","state"],"backgroundTag":"double-initialization","analyzedSha":"a33fdbf4c98034f4bfeeaea9868909822b9c526d","analyzedAt":"2026-09-02T22:15:54.506Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}