{"record":{"id":"e3405af3bcb9deaf","repo":"AdguardTeam/AdGuardHome","slug":"decoding-u-d-w","errorCode":null,"errorMessage":"decoding u%d: %w","messagePattern":"decoding u(.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dhcpd/options_unix.go","lineNumber":96,"sourceCode":"// parseDHCPOptionDur parses a DHCP option as a duration in a human-readable\n// form.\nfunc parseDHCPOptionDur(s string) (val dhcpv4.OptionValue, err error) {\n\tvar v timeutil.Duration\n\terr = v.UnmarshalText([]byte(s))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"decoding dur: %w\", err)\n\t}\n\n\treturn dhcpv4.Duration(v), nil\n}\n\n// parseDHCPOptionUint parses a DHCP option as an unsigned integer.  bitSize is\n// expected to be 8 or 16.\nfunc parseDHCPOptionUint(s string, bitSize int) (val dhcpv4.OptionValue, err error) {\n\tvar v uint64\n\tv, err = strconv.ParseUint(s, 10, bitSize)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"decoding u%d: %w\", bitSize, err)\n\t}\n\n\tswitch bitSize {\n\tcase 8:\n\t\treturn dhcpv4.OptionGeneric{Data: []byte{uint8(v)}}, nil\n\tcase 16:\n\t\treturn dhcpv4.Uint16(v), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported size of integer %d\", bitSize)\n\t}\n}\n\n// parseDHCPOptionBool parses a DHCP option as a boolean value.  See\n// [strconv.ParseBool] for available values.\nfunc parseDHCPOptionBool(s string) (val dhcpv4.OptionValue, err error) {\n\tvar v bool\n\tv, err = strconv.ParseBool(s)\n\tif err != nil {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/dhcpd/options_unix.go#L78-L114","documentation":"Returned by parseDHCPOptionUint when a DHCP option typed u8 or u16 fails strconv.ParseUint with the given bit size. The message embeds the bit size ('decoding u8:' / 'decoding u16:'). Values must be base-10 integers within 0–255 (u8) or 0–65535 (u16).","triggerScenarios":"Setting a u8 option to 256+, a negative number, a hex value like 0x2A, or a non-numeric string; a u16 option above 65535; empty string.","commonSituations":"Copy-pasting MTU or TTL values with units ('1500 bytes'); vendor tables listing option values in hex; off-by-one assumptions about inclusive bounds.","solutions":["Clamp to range: 0–255 for u8, 0–65535 for u16, decimal only","Strip units and whitespace from the value","Double-check the vendor's option table for whether the value is decimal or hex and convert to decimal"],"exampleFix":"// before\n{\"code\":21,\"type\":\"u8\",\"value\":\"300\"}\n// -> decoding u8: strconv.ParseUint: parsing \"300\": value out of range\n\n// after\n{\"code\":21,\"type\":\"u8\",\"value\":\"255\"}","handlingStrategy":"validation","validationCode":"func uintOK(s string, bits int) bool {\n\tv, err := strconv.ParseUint(strings.TrimSpace(s), 10, bits)\n\treturn err == nil && (bits == 8 && v <= 255 || bits == 16 && v <= 65535)\n}","typeGuard":null,"tryCatchPattern":"if _, err := strconv.ParseUint(s, 10, bitSize); err != nil {\n    if ne, ok := err.(*strconv.NumError); ok && ne.Err == strconv.ErrRange {\n        // value exceeds 255/65535: clamp or reject\n    }\n}","preventionTips":["Decimal-only values in 0–255 (u8) / 0–65535 (u16)","Strip units like 'bytes' from vendor tables","Convert hex codes to decimal before entering"],"tags":["dhcp","options","validation","configuration","integer-range"],"backgroundTag":"integer-out-of-range","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}