{"id":"80f0e21011499bb2","repo":"go-sql-driver/mysql","slug":"invalid-time-bytes-s","errorCode":null,"errorMessage":"invalid time bytes: %s","messagePattern":"invalid time bytes: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"utils.go","lineNumber":179,"sourceCode":"\n\t\tsec, err := parseByte2Digits(b[17], b[18])\n\t\tif err != nil {\n\t\t\treturn time.Time{}, err\n\t\t}\n\t\tif len(b) == 19 {\n\t\t\treturn time.Date(year, month, day, hour, min, sec, 0, loc), nil\n\t\t}\n\n\t\tif b[19] != '.' {\n\t\t\treturn time.Time{}, fmt.Errorf(\"bad value for field: `%c`\", b[19])\n\t\t}\n\t\tnsec, err := parseByteNanoSec(b[20:])\n\t\tif err != nil {\n\t\t\treturn time.Time{}, err\n\t\t}\n\t\treturn time.Date(year, month, day, hour, min, sec, nsec, loc), nil\n\tdefault:\n\t\treturn time.Time{}, fmt.Errorf(\"invalid time bytes: %s\", b)\n\t}\n}\n\nfunc parseByteYear(b []byte) (int, error) {\n\tyear, n := 0, 1000\n\tfor i := range 4 {\n\t\tv, err := bToi(b[i])\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tyear += v * n\n\t\tn /= 10\n\t}\n\treturn year, nil\n}\n\nfunc parseByte2Digits(b1, b2 byte) (int, error) {\n\td1, err := bToi(b1)","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/c426bd93799de0f0e094c8f0582872c529d0ed0a/utils.go#L161-L197","documentation":"Thrown by parseDateTime (utils.go:179) — the default branch of the length switch. It fires when the textual datetime byte length is NOT one of {10, 19, 21, 22, 23, 24, 25, 26} (the only legal MySQL DATE/DATETIME text lengths). The offending bytes are interpolated into the message, which is useful for diagnosing what the server actually sent.","triggerScenarios":"Scanning a DATE/DATETIME/TIMESTAMP column whose textual wire value has an unexpected length — e.g. an 8-byte 'YYYYMMDD', a 17-byte value, or trailing whitespace/garbage that changes the length class.","commonSituations":"Server returns a date in a compact 'YYYYMMDD' format (some compatibility modes / non-MySQL servers); a column declared DATETIME but holding a NULL-ish or zero-padded oddity; a proxy stripping or adding bytes; SQL_MODE NO_ZERO_DATE or similar producing unusual representations; a bug where a VARCHAR value reaches a time.Time scan.","solutions":["Look at the message: the %s shows the exact bytes. Compare against expected 'YYYY-MM-DD[ HH:MM:SS[.ffffff]]'.","If the format is legitimately different, SELECT the column CAST AS CHAR and parse with the matching time.Parse layout client-side.","Check the column type with SHOW COLUMNS / DESCRIBE — scan string columns as string, not time.Time.","Test directly against MySQL (bypassing proxies) to confirm the server itself emits the odd length."],"exampleFix":"// before: column is actually a VARCHAR holding '20200101'\nvar t time.Time\nerr := db.QueryRow(\"SELECT d FROM t\").Scan(&t)\n\n// after\nvar raw string\nif err := db.QueryRow(\"SELECT CAST(d AS CHAR) FROM t\").Scan(&raw); err == nil {\n    t, err = time.ParseInLocation(\"20060102\", raw, time.Local)\n}","handlingStrategy":"validation","validationCode":"// before scanning, confirm the textual length class is one MySQL produces\nvar raw string\nif err := db.QueryRow(\"SELECT CAST(d AS CHAR) FROM t WHERE id=?\", id).Scan(&raw); err != nil {\n    return err\n}\nswitch len(raw) {\ncase 10, 19, 21, 22, 23, 24, 25, 26:\n    t, err := time.ParseInLocation(\"2006-01-02 15:04:05.999999\", raw, time.Local)\n    _ = t\ndefault:\n    return fmt.Errorf(\"unexpected datetime length %d for %q\", len(raw), raw)\n}","typeGuard":null,"tryCatchPattern":"var t time.Time\nif err := rows.Scan(&t); err != nil {\n    if strings.Contains(err.Error(), \"invalid time bytes\") {\n        // length is unsupported; read as string and handle/log\n    }\n}","preventionTips":["Scan date-like columns into string first when their format is uncertain, then parse client-side.","Verify column DDL with SHOW COLUMNS to avoid scanning non-date types into time.Time.","Lock down server SQL_MODE so the textual datetime shape is stable."],"tags":["datetime","parsing","wire-format","protocol"],"analyzedSha":"c426bd93799de0f0e094c8f0582872c529d0ed0a","analyzedAt":"2026-08-04T21:52:59.219Z","schemaVersion":2}