go-sql-driver/mysql · warning

logger is nil

Error message

logger is nil

What it means

Returned by SetLogger (errors.go:57) when the caller passes nil. The package keeps a non-nil defaultLogger (os.Stderr) and refuses to replace it with nothing, because a nil logger would panic on the next critical-error log call.

Solutions

  1. Pass a concrete logger: the standard logger, a structured logger adapter, or mysql.NopLogger to silence output.
  2. Guard the call: only invoke SetLogger when your logger instance is non-nil.
  3. To disable logging deliberately, use mysql.SetLogger(mysql.NopLogger{}) instead of nil.

Example fix

// before
if logOut != nil {
    mysql.SetLogger(logOut)
} else {
    mysql.SetLogger(nil) // -> "logger is nil"
}

// after
if logOut != nil {
    mysql.SetLogger(logOut)
} else {
    mysql.SetLogger(mysql.NopLogger{})
}
Defensive patterns

Strategy: validation

Validate before calling

// Never pass nil; choose a real logger or the no-op one.
var l mysql.Logger = mysql.NopLogger{}
if appLogger != nil {
    l = appLogger // implements mysql.Logger
}
if err := mysql.SetLogger(l); err != nil {
    return err
}

Try / catch

if err := mysql.SetLogger(candidate); err != nil {
    if err.Error() == "logger is nil" {
        // pass mysql.NopLogger{} or a real logger instead
    }
}

Prevention

When it happens

Trigger: Calling mysql.SetLogger(nil), or passing a logger variable that was never initialized (defaults to nil interface).

Common situations: Conditionally configuring logging (e.g. only when a flag is set) and falling through to SetLogger(nil); refactoring that accidentally drops the logger assignment.

Related errors


AI-assisted analysis of go-sql-driver/mysql@03d76c7e07 (2026-08-07). Data as JSON: /api/errors/dabe3e5475d3d6a1. Report an issue: GitHub.

Appendix: source

Thrown at errors.go:57

var defaultLogger = Logger(log.New(os.Stderr, "[mysql] ", log.Ldate|log.Ltime))

// Logger is used to log critical error messages.
type Logger interface {
	Print(v ...any)
}

// NopLogger is a nop implementation of the Logger interface.
type NopLogger struct{}

// Print implements Logger interface.
func (nl *NopLogger) Print(_ ...any) {}

// SetLogger is used to set the default logger for critical errors.
// The initial logger is os.Stderr.
func SetLogger(logger Logger) error {
	if logger == nil {
		return errors.New("logger is nil")
	}
	defaultLogger = logger
	return nil
}

// MySQLError is an error type which represents a single MySQL error
type MySQLError struct {
	Number   uint16
	SQLState [5]byte
	Message  string
}

func (me *MySQLError) Error() string {
	if me.SQLState != [5]byte{} {
		return fmt.Sprintf("Error %d (%s): %s", me.Number, me.SQLState, me.Message)
	}

	return fmt.Sprintf("Error %d: %s", me.Number, me.Message)

View on GitHub (pinned to 03d76c7e07)