{"record":{"id":"b5322968218b0bf0","repo":"grpc/grpc-go","slug":"transport-timeout-string-is-too-long-q","errorCode":null,"errorMessage":"transport: timeout string is too long: %q","messagePattern":"transport: timeout string is too long: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/transport/http_util.go","lineNumber":195,"sourceCode":"\tcase millisecond:\n\t\treturn time.Millisecond, true\n\tcase microsecond:\n\t\treturn time.Microsecond, true\n\tcase nanosecond:\n\t\treturn time.Nanosecond, true\n\tdefault:\n\t}\n\treturn\n}\n\nfunc decodeTimeout(s string) (time.Duration, error) {\n\tsize := len(s)\n\tif size < 2 {\n\t\treturn 0, fmt.Errorf(\"transport: timeout string is too short: %q\", s)\n\t}\n\tif size > 9 {\n\t\t// Spec allows for 8 digits plus the unit.\n\t\treturn 0, fmt.Errorf(\"transport: timeout string is too long: %q\", s)\n\t}\n\tunit := timeoutUnit(s[size-1])\n\td, ok := timeoutUnitToDuration(unit)\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"transport: timeout unit is not recognized: %q\", s)\n\t}\n\tt, err := strconv.ParseUint(s[:size-1], 10, 64)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tconst maxHours = math.MaxInt64 / uint64(time.Hour)\n\tif d == time.Hour && t > maxHours {\n\t\t// This timeout would overflow math.MaxInt64; clamp it.\n\t\treturn time.Duration(math.MaxInt64), nil\n\t}\n\treturn d * time.Duration(t), nil\n}\n","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/transport/http_util.go#L177-L213","documentation":"This error occurs in decodeTimeout when the grpc-timeout header value exceeds 9 characters (8 digits + 1 unit character per the gRPC HTTP/2 spec). This is a protocol-level violation — the spec caps the numeric portion at 8 digits.","triggerScenarios":"A peer sends a grpc-timeout header with more than 8 digits before the unit, e.g., \"123456789S\". This violates the gRPC over HTTP/2 specification which limits the value to fit in 8 decimal digits.","commonSituations":"A buggy or non-compliant gRPC client/library generates an oversized timeout encoding, or an intermediary modifies the header. Extremely large deadline values that overflow the normal encoding could trigger this if the encoding logic is broken.","solutions":["Capture the raw grpc-timeout header value from the failing request to confirm it exceeds 8 digits.","Fix the client library or proxy generating the oversized value.","Ensure your gRPC client library is up to date with proper timeout encoding."],"exampleFix":"// before (broken): more than 8 digits in timeout\ngrpc-timeout: \"999999999S\"\n\n// after (valid): use a larger unit or clamp the value\ngrpc-timeout: \"9999H\"","handlingStrategy":"validation","validationCode":"func validateGrpcTimeout(s string) error {\n    if len(s) > 9 {\n        return fmt.Errorf(\"timeout too long: max 8 digits + unit\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a compliant gRPC client library with correct timeout encoding.","When setting very long deadlines, use larger units (H) to avoid exceeding 8 digits.","Monitor server logs for protocol violations to catch non-compliant peers."],"tags":["transport","http2","timeout","header-parsing","network","protocol-violation"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}