{"record":{"id":"f1381eb9677a394c","repo":"fatedier/frp","slug":"invalid-limiter-burst-d","errorCode":null,"errorMessage":"invalid limiter burst: %d","messagePattern":"invalid limiter burst: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/util/limit/limiter.go","lineNumber":36,"sourceCode":"\t\"fmt\"\n\n\t\"golang.org/x/time/rate\"\n)\n\n// NewBandwidthLimiter creates a limiter whose rate preserves the configured\n// byte limit while keeping the burst representable as an int on all targets.\nfunc NewBandwidthLimiter(bytes int64) *rate.Limiter {\n\tif bytes <= 0 {\n\t\treturn nil\n\t}\n\n\tmaxInt := int64(^uint(0) >> 1)\n\tburst := min(bytes, maxInt)\n\treturn rate.NewLimiter(rate.Limit(float64(bytes)), int(burst))\n}\n\nfunc invalidBurstError(burst int) error {\n\treturn fmt.Errorf(\"invalid limiter burst: %d\", burst)\n}\n","sourceCodeStart":18,"sourceCodeEnd":38,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/util/limit/limiter.go#L18-L38","documentation":"invalidBurstError was meant to flag a bandwidth limiter burst value that does not fit in an int (needed because x/time/rate takes burst as int while bandwidth is int64). In the current code it is unused dead code: NewBandwidthLimiter clamps the burst with min(bytes, maxInt) and returns a valid limiter for any positive bytes, returning nil for bytes <= 0. No runtime path can emit this error in this version.","triggerScenarios":"None in the shipped code — the function is never called. It would only fire in older or forked versions that validated burst before clamping, when the configured bytes-per-second exceeded math.MaxInt on 32-bit platforms.","commonSituations":"Grepping the codebase; using a fork that still calls invalidBurstError; seeing it referenced in old issues about bandwidth limits on 32-bit builds.","solutions":["Current versions: nothing to fix — the value is clamped; no error can occur.","Forks: replace validation with clamping as upstream does (burst := min(bytes, maxInt)).","Callers should treat a nil return from NewBandwidthLimiter as 'no limiting', which is how bytes <= 0 is handled."],"exampleFix":"// fork pattern — before\nburst := int(bytes)\nif int64(burst) != bytes {\n    return nil, invalidBurstError(burst) // can panic/fire on 32-bit\n}\n\n// after (upstream behavior)\nmaxInt := int64(^uint(0) >> 1)\nburst := min(bytes, maxInt)\nreturn rate.NewLimiter(rate.Limit(float64(bytes)), int(burst))","handlingStrategy":"validation","validationCode":"// callers: NewBandwidthLimiter returns nil when no limit applies — guard it\nlimiter := limit.NewBandwidthLimiter(cfg.BandwidthLimit)\nif limiter == nil {\n    // bandwidth limit unset or <= 0: skip wrapping the conn\n    return rawConn, nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["No runtime defense needed — the error is dead code in current versions.","Fork maintainers: clamp burst with min(bytes, maxInt) instead of validating and erroring.","On 32-bit targets, keep bandwidth values below math.MaxInt to avoid platform surprises."],"tags":["rate-limiting","dead-code","platform","bandwidth"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}