go-sql-driver/mysql · error
invalid TIME packet length
Error message
invalid TIME packet length %d
What it means
Raised by formatBinaryTime (utils.go:465) for the actual PAYLOAD length. The MySQL binary protocol encodes a TIME value as exactly 8 bytes (no fractional) or 12 bytes (with fractional seconds). Any other slice length means the value is malformed or the packet read pointer is desynchronized, so the driver refuses to format it.
Solutions
- Verify server/proxy compatibility; upgrade or replace the offending component.
- Cast the TIME column to CHAR in SQL, or scan it as raw []byte and parse manually.
- Switch the query to the text protocol (non-prepared) for the affected statement.
- Restart the connection to clear desync state.
Example fix
-- avoid binary TIME decoding entirely SELECT CAST(duration AS CHAR) AS duration FROM t WHERE id = ?; var s string db.QueryRow(query, id).Scan(&s)
Defensive patterns
Strategy: try-catch
Validate before calling
// Payload length is server-controlled; validate protocol compliance instead.
func isStandardBinaryTimePacketLen(n int) bool {
switch n {
case 8, 12:
return true
}
return false
} Type guard
func isStandardBinaryTimePacketLen(n int) bool {
switch n {
case 8, 12:
return true
}
return false
} Try / catch
var s string
if err := db.QueryRow(q, id).Scan(&s); err != nil {
if strings.Contains(err.Error(), "invalid TIME packet length") {
var raw []byte
_ = db.QueryRow(`SELECT CAST(dur AS CHAR) FROM t WHERE id=?`, id).Scan(&raw)
s = string(raw)
}
} Prevention
- Read TIME columns as CAST(... AS CHAR) through non-conforming servers.
- Restart the pool after packet errors to recover from desync.
- Pin and test server/proxy versions for TIME handling.
When it happens
Trigger: Reading a TIME column via a prepared statement (parseTime=false) when the server returns a binary value whose length is not 8 or 12. Reached via formatBinaryTime at packets.go:1414 with src = data[pos:pos+num]. Indicates truncation, packet desync, or a non-conforming server.
Common situations: Result-set desync after an earlier malformed packet, a proxy mishandling TIME values, network corruption, or a server fork with non-standard TIME encoding.
Related errors
- illegal packet length
- illegal TIME length
- illegal length
- invalid DATETIME packet length
- can't convert %T to time.Time
AI-assisted analysis of go-sql-driver/mysql@03d76c7e07 (2026-08-07).
Data as JSON: /api/errors/f558e77f8fce7b43.
Report an issue: GitHub.
Appendix: 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 03d76c7e07)