{"record":{"id":"88e2b4fcf36aa088","repo":"nsqio/nsq","slug":"err-error-88e2b4","errorCode":null,"errorMessage":"err.Error()","messagePattern":"err\\.Error\\(\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bench/bench_writer/bench_writer.go","lineNumber":77,"sourceCode":"\t}\n\n\tstart := time.Now()\n\tclose(goChan)\n\twg.Wait()\n\tend := time.Now()\n\tduration := end.Sub(start)\n\ttmc := atomic.LoadInt64(&totalMsgCount)\n\tlog.Printf(\"duration: %s - %.03fmb/s - %.03fops/s - %.03fus/op\",\n\t\tduration,\n\t\tfloat64(tmc*int64(*size))/duration.Seconds()/1024/1024,\n\t\tfloat64(tmc)/duration.Seconds(),\n\t\tfloat64(duration/time.Microsecond)/float64(tmc))\n}\n\nfunc pubWorker(td time.Duration, tcpAddr string, batchSize int, batch [][]byte, topic string, rdyChan chan int, goChan chan int) {\n\tconn, err := net.DialTimeout(\"tcp\", tcpAddr, time.Second)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\t_, err = conn.Write(nsq.MagicV2)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\trw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))\n\tci := make(map[string]interface{})\n\tci[\"client_id\"] = \"writer\"\n\tci[\"hostname\"] = \"writer\"\n\tci[\"user_agent\"] = fmt.Sprintf(\"bench_writer/%s\", nsq.VERSION)\n\tcmd, _ := nsq.Identify(ci)\n\t_, err = cmd.WriteTo(rw)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\trdyChan <- 1\n\t<-goChan\n\terr = rw.Flush()","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/nsqio/nsq/blob/85cf10c09c6c3c86160d6f0eb156f62d0efc1648/bench/bench_writer/bench_writer.go#L59-L95","documentation":"bench_writer panics when net.DialTimeout(\"tcp\", tcpAddr, time.Second) fails while connecting a publisher worker to nsqd: dial error or no completion within 1s (timeout produces 'i/o timeout'). err.Error() is the panic message. All pubWorker goroutines crash the process on any single failed dial; no retry exists.","triggerScenarios":"nsqd not started/listening yet; wrong --nsqd-tcp-address; 1-second dial budget exceeded on slow networks, DNS delays, or under connection storms with many parallel workers; firewall dropping SYN (timeout rather than refused).","commonSituations":"Launching bench_writer in a script before nsqd is ready (race); remote/high-latancy nsqd where 1s is tight; huge -c (workers) counts causing accept-queue saturation during dial; container networks with slow DNS for hostnames.","solutions":["Verify nsqd is accepting: `nc -zv host 4150`, then start bench_writer.","Pass the correct flag: bench_writer --nsqd-tcp-address=127.0.0.1:4150.","If latency is real, patch DialTimeout's budget in bench_writer/bench_writer.go:77 to e.g. 5*time.Second (it is a benchmark tool; local edits are fine).","Reduce -c workers or stagger startup so the accept queue does not overflow."],"exampleFix":"// before\nconn, err := net.DialTimeout(\"tcp\", tcpAddr, time.Second)\nif err != nil {\n\tpanic(err.Error())\n}\n\n// after\nconn, err := net.DialTimeout(\"tcp\", tcpAddr, 5*time.Second)\nif err != nil {\n\tlog.Fatalf(\"dial %s: %v\", tcpAddr, err)\n}","handlingStrategy":"validation","validationCode":"conn, err := net.DialTimeout(\"tcp\", addr, time.Second)\nif err != nil { log.Fatalf(\"nsqd unreachable at %s: %v\", addr, err) }\nconn.Close()\n// only then start bench_writer","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        log.Fatalf(\"bench_writer dial failed: %v\", r)\n    }\n}()","preventionTips":["Sequence startup: nsqd healthy -> bench_writer (add wait-for-port in scripts).","Double-check --nsqd-tcp-address; default bench port must match nsqd's 4150.","On high-latency links, locally bump the 1s DialTimeout in bench_writer.go."],"tags":["bench","nsq-client","panic","dial","timeout","tcp","go"],"backgroundTag":null,"analyzedSha":"85cf10c09c6c3c86160d6f0eb156f62d0efc1648","analyzedAt":"2026-08-16T00:53:05.009Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}