go-sql-driver/mysql · error
invalid time bytes
Error message
invalid time bytes: %s
What it means
Raised by parseDateTime (utils.go:179) in its default branch: the byte length of the text datetime value is none of the canonical lengths {10 (date), 19 (datetime), 21-26 (datetime with 1-6 fractional digits)}. The driver therefore has no parse template for the value and returns it verbatim in the error. Length is checked before any separator, so this fires for structurally wrong values (truncated, padded, or extra chars).
Solutions
- Identify the bad value: scan into string to capture it, then fix the stored data to a canonical length.
- If variable formats are unavoidable, disable parseTime and parse with the correct layout per row.
- Pad/normalize on write (LPAD month/day, enforce seconds) so values are always 10 or 19+ chars.
- Audit the table: SELECT col, LENGTH(col) FROM t WHERE LENGTH(col) NOT IN (10,19,21,22,23,24,25,26) to find offenders.
Example fix
-- find offending rows
SELECT id, the_col, LENGTH(the_col) AS len
FROM events
WHERE LENGTH(the_col) NOT IN (10,19,21,22,23,24,25,26);
// Go: read raw and coerce
var raw string
rows.Scan(&raw)
t, err := time.Parse("2006-1-2 15:04:05", strings.TrimSpace(raw)) Defensive patterns
Strategy: validation
Validate before calling
func isValidMySQLDateTimeLen(s string) bool {
switch len(s) {
case 10, 19, 21, 22, 23, 24, 25, 26:
return true
}
return false
} Type guard
func hasCanonicalDateTimeLength(b []byte) bool {
switch len(b) {
case 10, 19, 21, 22, 23, 24, 25, 26:
return true
}
return false
} Try / catch
var t time.Time
if err := rows.Scan(&t); err != nil && strings.Contains(err.Error(), "invalid time bytes") {
var raw string
// inspect raw value/length and repair
} Prevention
- Audit tables: SELECT col, LENGTH(col) WHERE LENGTH NOT IN (10,19,21,22,23,24,25,26).
- Zero-pad month/day and always include seconds on insert.
- Trim whitespace from imported values before insert.
- Disable parseTime for tables with known inconsistent formatting.
When it happens
Trigger: Scanning a DATE/DATETIME/TIMESTAMP column into time.Time (parseTime=true) or sql.NullTime when the server's text value length is not 10/19/21-26 — e.g. '2020-1-1' (single digits, len 8), '2020-01-01 00:00' (len 16), values with trailing whitespace/garbage, or an empty-but-non-null value. Reached via parseDateTime at packets.go:875 / nulltime.go:52.
Common situations: Single-digit month/day (no zero padding), DATETIME values with seconds omitted, rows containing trailing characters or whitespace, mis-typed columns (VARCHAR holding a near-date), or hand-written import files with inconsistent formatting.
Related errors
AI-assisted analysis of go-sql-driver/mysql@03d76c7e07 (2026-08-07).
Data as JSON: /api/errors/80f0e21011499bb2.
Report an issue: GitHub.
Appendix: source
Thrown at utils.go:179
sec, err := parseByte2Digits(b[17], b[18])
if err != nil {
return time.Time{}, err
}
if len(b) == 19 {
return time.Date(year, month, day, hour, min, sec, 0, loc), nil
}
if b[19] != '.' {
return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[19])
}
nsec, err := parseByteNanoSec(b[20:])
if err != nil {
return time.Time{}, err
}
return time.Date(year, month, day, hour, min, sec, nsec, loc), nil
default:
return time.Time{}, fmt.Errorf("invalid time bytes: %s", b)
}
}
func parseByteYear(b []byte) (int, error) {
year, n := 0, 1000
for i := range 4 {
v, err := bToi(b[i])
if err != nil {
return 0, err
}
year += v * n
n /= 10
}
return year, nil
}
func parseByte2Digits(b1, b2 byte) (int, error) {
d1, err := bToi(b1)View on GitHub (pinned to 03d76c7e07)