{"record":{"id":"3f5dd2ff43a6afd5","repo":"go-sql-driver/mysql","slug":"strict-mode-has-been-removed-see-https-github-c","errorCode":null,"errorMessage":"strict mode has been removed. See https://github.com/go-sql-driver/mysql/wiki/strict-mode","messagePattern":"strict mode has been removed\\. See https://github\\.com/go-sql-driver/mysql/wiki/strict-mode","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"dsn.go","lineNumber":638,"sourceCode":"\t\t// Reject read-only connections\n\t\tcase \"rejectReadOnly\":\n\t\t\tvar isBool bool\n\t\t\tcfg.RejectReadOnly, isBool = readBool(value)\n\t\t\tif !isBool {\n\t\t\t\treturn errors.New(\"invalid bool value: \" + value)\n\t\t\t}\n\n\t\t// Server public key\n\t\tcase \"serverPubKey\":\n\t\t\tname, err := url.QueryUnescape(value)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"invalid value for server pub key name: %v\", err)\n\t\t\t}\n\t\t\tcfg.ServerPubKey = name\n\n\t\t// Strict mode\n\t\tcase \"strict\":\n\t\t\tpanic(\"strict mode has been removed. See https://github.com/go-sql-driver/mysql/wiki/strict-mode\")\n\n\t\t// Dial Timeout\n\t\tcase \"timeout\":\n\t\t\tcfg.Timeout, err = time.ParseDuration(value)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t// TLS-Encryption\n\t\tcase \"tls\":\n\t\t\tboolValue, isBool := readBool(value)\n\t\t\tif isBool {\n\t\t\t\tif boolValue {\n\t\t\t\t\tcfg.TLSConfig = \"true\"\n\t\t\t\t} else {\n\t\t\t\t\tcfg.TLSConfig = \"false\"\n\t\t\t\t}\n\t\t\t} else if vl := strings.ToLower(value); vl == \"skip-verify\" || vl == \"preferred\" {","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/03d76c7e07908e255ce62d126d07ede3f2365d86/dsn.go#L620-L656","documentation":"This is a hard PANIC (not a returned error) raised during DSN parsing (dsn.go:638) when the connection string contains the 'strict' parameter. The 'strict' DSN option was removed in go-sql-driver/mysql v1.0 (2016) because its behavior is better achieved with collation and parseTime settings. Because sql.Open parses the DSN lazily, this panic typically crashes the process on the first real connection attempt unless recovered.","triggerScenarios":"Passing a DSN containing 'strict=true' (or strict=anything) to sql.Open(\"mysql\", ...). The DSN switch in parseDSNParams hits case \"strict\" and calls panic(). Since sql.Open itself does not parse params eagerly, the panic fires on first use (Ping/Query) when database/sql builds the connector.","commonSituations":"Upgrading an old codebase from go-sql-driver v0.x to v1.x without removing the legacy 'strict' DSN option; copy-pasting a DSN from an old tutorial; CI working locally with strict removed but a deployed config still carrying it; vendoring an old example.","solutions":["Remove the 'strict=true' (or 'strict=...') parameter from the DSN entirely.","If you relied on strict's error-on-truncate behavior, set sql_mode=STRICT_TRANS_TABLES (or STRICT_ALL_TABLES) on the server / via the DSN 'sql_mode' param instead.","If you relied on strict's time parsing, add parseTime=true and, if needed, loc=... to the DSN.","After removing, run sql.Open then db.Ping() in a test to confirm no panic."],"exampleFix":"// before\nsql.Open(\"mysql\", \"user:pass@tcp(127.0.0.1:3306)/db?strict=true\")\n\n// after\nsql.Open(\"mysql\", \"user:pass@tcp(127.0.0.1:3306)/db?parseTime=true&sql_mode=STRICT_TRANS_TABLES\")","handlingStrategy":"validation","validationCode":"// Validate the DSN before handing it to sql.Open.\nfunc hasRemovedStrictParam(dsn string) bool {\n    for _, param := range strings.Split(strings.SplitN(dsn, \"?\", 2)[1], \"&\") {\n        if strings.HasPrefix(param, \"strict=\") {\n            return true\n        }\n    }\n    return false\n}\n\nif hasRemovedStrictParam(dsn) {\n    log.Fatal(\"DSN uses removed 'strict' param; remove it and use sql_mode/parseTime instead\")\n}","typeGuard":"func dsnIsStrictFree(dsn string) bool {\n    q := strings.SplitN(dsn, \"?\", 2)\n    if len(q) < 2 { return true }\n    for _, p := range strings.Split(q[1], \"&\") {\n        if strings.HasPrefix(p, \"strict=\") { return false }\n    }\n    return true\n}","tryCatchPattern":"// parseDSN panics, so recover if you handle untrusted DSNs.\ndefer func() {\n    if r := recover(); r != nil {\n        if s, ok := r.(string); ok && strings.Contains(s, \"strict mode has been removed\") {\n            // strip the strict param and retry, or surface a clear config error\n        } else {\n            panic(r) // re-raise unrelated panics\n        }\n    }\n}()\ndb, err := sql.Open(\"mysql\", dsn)","preventionTips":["Remove 'strict=' from all DSNs when upgrading to go-sql-driver/mysql v1.x.","Replace strict's behavior with sql_mode=STRICT_TRANS_TABLES and parseTime=true.","Gate sql.Open with a DSN lint that rejects 'strict=' on startup.","Add a smoke test calling db.Ping() in CI to catch panics early."],"tags":["mysql","dsn","configuration","panic","migration","version-change"],"backgroundTag":null,"analyzedSha":"03d76c7e07908e255ce62d126d07ede3f2365d86","analyzedAt":"2026-08-07T10:39:17.340Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}