go-sql-driver/mysql · error
invalid TIME packet length %d
Error message
invalid TIME packet length %d
What it means
Thrown by formatBinaryTime (utils.go:465) when the ACTUAL payload byte length of a binary TIME value is not in {8, 12} — the only valid binary TIME payload sizes (8 bytes without fraction, 12 with micros). Distinct from error 49 which checks the declared length; this checks the bytes actually received.
Source
Thrown at utils.go:465
func formatBinaryTime(src []byte, length uint8) (driver.Value, error) {
// length expects the deterministic length of the zero value,
// negative time and 100+ hours are automatically added if needed
if len(src) == 0 {
return zeroDateTime[11 : 11+length], nil
}
var dst []byte // return value
switch length {
case
8, // time (can be up to 10 when negative and 100+ hours)
10, 11, 12, 13, 14, 15: // time with fractional seconds
default:
return nil, fmt.Errorf("illegal TIME length %d", length)
}
switch len(src) {
case 8, 12:
default:
return nil, fmt.Errorf("invalid TIME packet length %d", len(src))
}
// +2 to enable negative time and 100+ hours
dst = make([]byte, 0, length+2)
if src[0] == 1 {
dst = append(dst, '-')
}
days := binary.LittleEndian.Uint32(src[1:5])
hours := int64(days)*24 + int64(src[5])
if hours >= 100 {
dst = strconv.AppendInt(dst, hours, 10)
} else {
dst = append(dst, digits10[hours], digits01[hours])
}
min, sec := src[6], src[7]
dst = append(dst, ':',
digits10[min], digits01[min], ':',View on GitHub (pinned to c426bd9379)
Solutions
- Note the actual length in the message; reproduce with the text protocol (CAST AS CHAR or plain Query) to confirm the binary path is at fault.
- Connect directly to MySQL, bypassing any proxy/router/tunnel.
- Verify the column type and server version with SHOW COLUMNS and SELECT VERSION().
- Report upstream if it reproduces against vanilla MySQL, including the length and column DDL.
Example fix
// before
var d time.Duration
db.QueryRow("SELECT elapsed FROM t WHERE id=?", id).Scan(&d)
// after: read text for diagnosis
var raw string
if err := db.QueryRow("SELECT TIME_FORMAT(elapsed, '%H:%i:%s') FROM t WHERE id=?", id).Scan(&raw); err == nil {
// parse manually
} Defensive patterns
Strategy: try-catch
Try / catch
if err := rows.Scan(...); err != nil {
if strings.Contains(err.Error(), "invalid TIME packet length") {
// binary TIME payload size wrong; fall back to text protocol
}
} Prevention
- For flaky binary-row links, read TIME columns via TIME_FORMAT(...) or CAST AS CHAR (text protocol).
- Eliminate network components that truncate binary TIME payloads.
- Validate server version supports the binary TIME shapes you depend on.
When it happens
Trigger: Reading a TIME column via the binary protocol where the row packet's TIME payload has a byte count other than 8 or 12 — truncated packet, padding corruption, non-conforming server. Fires during Scan on prepared-statement rows touching a TIME column.
Common situations: Truncated/corrupted binary row data over a flaky network; a proxy/router mishandling binary TIME payloads; server-version mismatch; rare memory corruption. The message reports the actual invalid length.
Related errors
- illegal TIME length %d
- invalid DATETIME packet length %d
- illegal %s length %d
- illegal %s packet length %d
- protocol error, illegal decimals value %d
AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04).
Data as JSON: /data/errors/f558e77f8fce7b43.json.
Report an issue: GitHub.