{"record":{"id":"78e3b09ae567f64c","repo":"fatedier/frp","slug":"unit-not-support","errorCode":null,"errorMessage":"unit not support","messagePattern":"unit not support","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/types/types.go","lineNumber":80,"sourceCode":"func (q *BandwidthQuantity) UnmarshalString(s string) error {\n\ts = strings.TrimSpace(s)\n\tif s == \"\" {\n\t\treturn nil\n\t}\n\n\tvar (\n\t\tbase int64\n\t\tf    float64\n\t\terr  error\n\t)\n\tif fstr, ok := strings.CutSuffix(s, \"MB\"); ok {\n\t\tbase = MB\n\t\tf, err = strconv.ParseFloat(fstr, 64)\n\t} else if fstr, ok := strings.CutSuffix(s, \"KB\"); ok {\n\t\tbase = KB\n\t\tf, err = strconv.ParseFloat(fstr, 64)\n\t} else {\n\t\treturn errors.New(\"unit not support\")\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tq.s = s\n\tq.i = int64(f * float64(base))\n\treturn nil\n}\n\nfunc (q *BandwidthQuantity) UnmarshalJSON(b []byte) error {\n\tif len(b) == 4 && string(b) == \"null\" {\n\t\treturn nil\n\t}\n\n\tvar str string\n\terr := json.Unmarshal(b, &str)\n\tif err != nil {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/types/types.go#L62-L98","documentation":"BandwidthQuantity.UnmarshalJSON (pkg/config/types/types.go:80) accepts only strings suffixed with KB or MB (e.g. \"1MB\", \"512KB\"); any other unit — or a bare number string — hits the else branch and returns 'unit not support'. Bandwidth values in frp configs are parsed through this type (bandwidthLimit fields).","triggerScenarios":"Setting bandwidthLimit = \"1GB\", bandwidthLimit = \"100\", bandwidthLimit = \"10mbps\", or any value whose suffix is not exactly KB/MB (case-sensitive per CutSuffix), then starting frpc/frps or reloading — config decode fails at that field.","commonSituations":"Assuming GB or Mbps are accepted because other tools use them; pasting bandwidth numbers without units; casing differences like 'Mb'; upgrading from configs that were never validated strictly.","solutions":["Express the limit in KB or MB, e.g. \"1024KB\" or \"1MB\" (convert 1GB to \"1024MB\")","Remove bandwidthLimit when no limit is intended","Fix casing: suffix must be exactly 'KB' or 'MB'","Validate bandwidth strings with a ^\\d+(\\.\\d+)?(KB|MB)$ check in your config pipeline"],"exampleFix":"# before\ntransport.bandwidthLimit = \"100MBps\"\n# or\nproxies[0].transport.bandwidthLimit = \"1GB\"\n\n# after\ntransport.bandwidthLimit = \"100MB\"\nproxies[0].transport.bandwidthLimit = \"1024MB\"","handlingStrategy":"validation","validationCode":"var bandwidthRe = regexp.MustCompile(`^\\d+(\\.\\d+)?(KB|MB)$`)\n\nif !bandwidthRe.MatchString(cfg.Transport.BandwidthLimit) {\n    return fmt.Errorf(\"bandwidthLimit %q must end in KB or MB\", cfg.Transport.BandwidthLimit)\n}","typeGuard":null,"tryCatchPattern":"if err := json.Unmarshal(data, &cfg); err != nil {\n    if strings.Contains(err.Error(), \"unit not support\") {\n        return fmt.Errorf(\"bandwidth values must be like \\\"1MB\\\" or \\\"512KB\\\" (GB/Mbps/bare numbers unsupported)\")\n    }\n    return err\n}","preventionTips":["Standardize bandwidth config generation on KB/MB suffixes only","Lint configs with the regex before deploying","Remember the check is case-sensitive: exactly 'KB'/'MB'"],"tags":["go","configuration","bandwidth","parsing"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}