go-sql-driver/mysql · error
bad value for field: `%c`
Error message
bad value for field: `%c`
What it means
Returned by parseDateTime (utils.go:121) when parsing a textual datetime and the byte at position 4 is not `-`. Position 4 is the year-month separator in the `YYYY-MM-DD ...` layout, so a wrong character means the string does not follow the expected format. parseDateTime is used when reading DATETIME/TIMESTAMP columns (with parseTime=true) and by nulltime.go.
Source
Thrown at utils.go:121
/******************************************************************************
* Time related utils *
******************************************************************************/
func parseDateTime(b []byte, loc *time.Location) (time.Time, error) {
const base = "0000-00-00 00:00:00.000000"
switch len(b) {
case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM"
if string(b) == base[:len(b)] {
return time.Time{}, nil
}
year, err := parseByteYear(b)
if err != nil {
return time.Time{}, err
}
if b[4] != '-' {
return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[4])
}
m, err := parseByte2Digits(b[5], b[6])
if err != nil {
return time.Time{}, err
}
month := time.Month(m)
if b[7] != '-' {
return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[7])
}
day, err := parseByte2Digits(b[8], b[9])
if err != nil {
return time.Time{}, err
}
if len(b) == 10 {
return time.Date(year, month, day, 0, 0, 0, 0, loc), nilView on GitHub (pinned to c426bd9379)
Solutions
- Inspect and fix the stored data so it matches `YYYY-MM-DD[ HH:MM:SS[.ffffff]]`.
- Ensure the application writes proper DATETIME values, not free-form strings.
- Tighten sql_mode on the server (STRICT_TRANS_TABLES) so malformed values cannot be stored.
Example fix
// before: column holds '2024/01/01 00:00:00' SELECT dt FROM t; // parseDateTime fails on '/' at b[4] // after: normalize the data UPDATE t SET dt = REPLACE(dt, '/', '-') WHERE dt LIKE '____/__/__%';
Defensive patterns
Strategy: validation
Validate before calling
if len(s) >= 5 && s[4] != '-' {
return fmt.Errorf("datetime %q has bad year-month separator", s)
} Type guard
func looksLikeDatetime(s string) bool { return len(s) >= 10 && s[4] == '-' && s[7] == '-' } Prevention
- Enforce STRICT sql_mode to keep DATETIME columns well-formed.
- Validate date strings before insert.
- Audit imported data for separator consistency.
When it happens
Trigger: Reading a row where a DATETIME/TIMESTAMP-valued column contains a string whose 5th byte is not '-', e.g. a value stored as `2024/01/01 ...` (slash separator) or otherwise corrupted, while the column length is one of the accepted sizes (10,19,21-26). utils.go:120-121 fires.
Common situations: A non-standard datetime format inserted via loose sql_mode; a column that is declared DATETIME but holds malformed/legacy data; a character-set/encoding issue altering bytes; application code writing strings instead of proper datetime values.
Related errors
- invalid timeTruncate value: %v, error: %w
- commands out of sync. Did you run multiple statements at onc
- packet for query is too large. Try adjusting the `Config.Max
- invalid time bytes: %s
- not [0-9]
AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04).
Data as JSON: /data/errors/90c6e55ad06c9cf2.json.
Report an issue: GitHub.