{"record":{"id":"729f8b5178fe26d6","repo":"nsqio/nsq","slug":"msg-timeout-d-is-invalid","errorCode":null,"errorMessage":"msg timeout (%d) is invalid","messagePattern":"msg timeout \\((.+?)\\) is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nsqd/client_v2.go","lineNumber":581,"sourceCode":"\tif sampleRate < 0 || sampleRate > 99 {\n\t\treturn fmt.Errorf(\"sample rate (%d) is invalid\", sampleRate)\n\t}\n\tatomic.StoreInt32(&c.SampleRate, sampleRate)\n\treturn nil\n}\n\nfunc (c *clientV2) SetMsgTimeout(msgTimeout int) error {\n\tc.writeLock.Lock()\n\tdefer c.writeLock.Unlock()\n\n\tswitch {\n\tcase msgTimeout == 0:\n\t\t// do nothing (use default)\n\tcase msgTimeout >= 1000 &&\n\t\tmsgTimeout <= int(c.nsqd.getOpts().MaxMsgTimeout/time.Millisecond):\n\t\tc.MsgTimeout = time.Duration(msgTimeout) * time.Millisecond\n\tdefault:\n\t\treturn fmt.Errorf(\"msg timeout (%d) is invalid\", msgTimeout)\n\t}\n\n\treturn nil\n}\n\nfunc (c *clientV2) UpgradeTLS() error {\n\tc.writeLock.Lock()\n\tdefer c.writeLock.Unlock()\n\n\ttlsConn := tls.Server(c.Conn, c.nsqd.tlsConfig)\n\tif err := tlsConn.SetDeadline(time.Now().Add(5 * time.Second)); err != nil {\n\t\treturn err\n\t}\n\terr := tlsConn.Handshake()\n\tif err != nil {\n\t\treturn err\n\t}\n\tc.tlsConn = tlsConn","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/nsqio/nsq/blob/85cf10c09c6c3c86160d6f0eb156f62d0efc1648/nsqd/client_v2.go#L563-L599","documentation":"IDENTIFY's msg_timeout field lets a client override how long nsqd waits before retrying a delivered message. clientV2.SetMsgTimeout accepts 0 (keep the --msg-timeout default, 60s) or milliseconds in [1000, --max-msg-timeout] (default 900000ms = 15m). Any other value returns this error and the IDENTIFY command fails.","triggerScenarios":"Sending msg_timeout: 500 (below the 1s floor), msg_timeout: 3600000 for a 1h timeout when max is 15m, or a negative number.","commonSituations":"Long-running handlers (batch jobs, ML inference, big file processing) wanting longer than 15m per attempt; unit confusion between seconds and milliseconds; tuning copied from a cluster with a raised --max-msg-timeout.","solutions":["Send 0 to use the server default or a millisecond value in [1000, 900000]","If handlers legitimately run longer, raise --max-msg-timeout on nsqd (and prefer designing idempotent, quickly-acking work)","Verify the unit is milliseconds"],"exampleFix":"// before\ncfg.MsgTimeout = 45 * time.Minute // 2700000ms > 15m max -> error on IDENTIFY\n\n// after\ncfg.MsgTimeout = 10 * time.Minute // 600000ms, within [1000,900000]","handlingStrategy":"validation","validationCode":"func clampMsgTimeout(ms, maxMs int) int {\n\tif ms == 0 {\n\t\treturn 0\n\t}\n\tif ms < 1000 { return 1000 }\n\tif ms > maxMs { return maxMs }\n\treturn ms\n}","typeGuard":null,"tryCatchPattern":"// connect-time config error: log desired vs [1000,max], fix duration, reconnect","preventionTips":["Set MsgTimeout via time.Duration in client libraries, never raw ints","Raise --max-msg-timeout on nsqd before shipping longer timeouts","Prefer short timeouts + idempotent handlers over multi-hour attempts"],"tags":["nsqd","protocol","identify","timeout","validation"],"backgroundTag":null,"analyzedSha":"85cf10c09c6c3c86160d6f0eb156f62d0efc1648","analyzedAt":"2026-08-16T00:53:05.009Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}