{"record":{"id":"5b622d8be25b9558","repo":"caddyserver/caddy","slug":"parsing-duration-input-string-too-long","errorCode":null,"errorMessage":"parsing duration: input string too long","messagePattern":"parsing duration: input string too long","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"caddy.go","lineNumber":892,"sourceCode":"\t}\n\tvar dur time.Duration\n\tvar err error\n\tif b[0] == byte('\"') && b[len(b)-1] == byte('\"') {\n\t\tdur, err = ParseDuration(strings.Trim(string(b), `\"`))\n\t} else {\n\t\terr = json.Unmarshal(b, &dur)\n\t}\n\t*d = Duration(dur)\n\treturn err\n}\n\n// ParseDuration parses a duration string, adding\n// support for the \"d\" unit meaning number of days,\n// where a day is assumed to be 24h. The maximum\n// input string length is 1024.\nfunc ParseDuration(s string) (time.Duration, error) {\n\tif len(s) > 1024 {\n\t\treturn 0, fmt.Errorf(\"parsing duration: input string too long\")\n\t}\n\tvar inNumber bool\n\tvar numStart int\n\tfor i := 0; i < len(s); i++ {\n\t\tch := s[i]\n\t\tif ch == 'd' {\n\t\t\tdaysStr := s[numStart:i]\n\t\t\tdays, err := strconv.ParseFloat(daysStr, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\thours := days * 24.0\n\t\t\thoursStr := strconv.FormatFloat(hours, 'f', -1, 64)\n\t\t\ts = s[:numStart] + hoursStr + \"h\" + s[i+1:]\n\t\t\ti--\n\t\t\tcontinue\n\t\t}\n\t\tif !inNumber {","sourceCodeStart":874,"sourceCodeEnd":910,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/caddy.go#L874-L910","documentation":"ParseDuration rejects any duration string longer than 1024 characters before attempting to parse. This is a cheap DoS guard for untrusted input (the parser is hand-written and O(n) over a potentially huge string). The 'd' (days) unit is a Caddy extension over time.ParseDuration.","triggerScenarios":"Calling caddy.ParseDuration (directly or via Duration.UnmarshalJSON, which routes strings through it) with a string longer than 1024 bytes. Any Caddyfile/JSON field typed as a duration that receives a giant value hits this.","commonSituations":"A config templating bug that repeats a unit many times (e.g. '1s' concatenated thousands of times), or adversarial input to an API that accepts duration strings. Normal configs never approach the limit.","solutions":["Find the offending duration field: the error appears during JSON unmarshal or Caddyfile parsing of a duration-typed field","Shorten the value to a sane duration using larger units (e.g. '8760h' or '365d' instead of repeated hours)","If generating durations programmatically, format with time.Duration.String() which never exceeds ~20 chars","For user-facing APIs, validate length before passing to ParseDuration"],"exampleFix":"// before\ndur, err := caddy.ParseDuration(userSuppliedMaybeHugeString)\n// after\nif len(userSuppliedMaybeHugeString) > 1024 {\n    return fmt.Errorf(\"duration too long\")\n}\ndur, err := caddy.ParseDuration(userSuppliedMaybeHugeString)","handlingStrategy":"validation","validationCode":"func parseDurationSafe(s string) (time.Duration, error) {\n    if len(s) > 1024 {\n        return 0, fmt.Errorf(\"duration string too long (%d bytes)\", len(s))\n    }\n    return caddy.ParseDuration(s)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cap input length at API boundaries that accept durations","Generate durations with time.Duration.String(), never string concatenation","Reject absurd durations (e.g. > 100 years) at validation time"],"tags":["duration","parse","input-validation"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}