ginuerzh/gost · error
obfs4 context already inited
Error message
obfs4 context already inited
What it means
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.
Source
Thrown at obfs.go:680
return
}
}
return
}
type obfs4Context struct {
cf base.ClientFactory
cargs interface{} // type obfs4ClientArgs
sf base.ServerFactory
sargs *pt.Args
}
var obfs4Map = make(map[string]obfs4Context)
// Obfs4Init initializes the obfs client or server based on isServeNode
func Obfs4Init(node Node, isServeNode bool) error {
if _, ok := obfs4Map[node.Addr]; ok {
return fmt.Errorf("obfs4 context already inited")
}
t := new(obfs4.Transport)
stateDir := node.Values.Get("state-dir")
if stateDir == "" {
stateDir = "."
}
ptArgs := pt.Args(node.Values)
if !isServeNode {
cf, err := t.ClientFactory(stateDir)
if err != nil {
return err
}
cargs, err := cf.ParseArgs(&ptArgs)View on GitHub (pinned to a33fdbf4c9)
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).
Example fix
// before
Obfs4Init(node, true) // second call on reload panics with this error
// after
if _, err := obfs4GetContext(node.Addr); err != nil {
Obfs4Init(node, true)
} Defensive patterns
Strategy: validation
Validate before calling
// guard your own init path
var inited = map[string]bool{}
func ensureObfsInit(node Node, serve bool) error {
if inited[node.Addr] { return nil }
if err := Obfs4Init(node, serve); err != nil { return err }
inited[node.Addr] = true
return nil
} Try / catch
if err := Obfs4Init(node, true); err != nil {
if strings.Contains(err.Error(), "already inited") {
return nil // idempotent no-op
}
return err
} Prevention
- Init each obfs4 address exactly once per process
- Track init state on config reload
- Use unique addresses per context
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/73033b034a5c5916.
Report an issue: GitHub.