golang-migrate/migrate · error

unable to parse option x-multi-statement: %w

Error message

unable to parse option x-multi-statement: %w

What it means

Open() in the postgres driver reads the x-multi-statement URL parameter and parses it as a boolean with strconv.ParseBool. If the value is not a valid boolean literal (1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False), the underlying parse error is wrapped and returned. The driver cannot safely enable multi-statement mode from an unparseable value.

Source

Thrown at database/postgres/postgres.go:199

		}
	}

	multiStatementMaxSize := DefaultMultiStatementMaxSize
	if s := purl.Query().Get("x-multi-statement-max-size"); len(s) > 0 {
		multiStatementMaxSize, err = strconv.Atoi(s)
		if err != nil {
			return nil, err
		}
		if multiStatementMaxSize <= 0 {
			multiStatementMaxSize = DefaultMultiStatementMaxSize
		}
	}

	multiStatementEnabled := false
	if s := purl.Query().Get("x-multi-statement"); len(s) > 0 {
		multiStatementEnabled, err = strconv.ParseBool(s)
		if err != nil {
			return nil, fmt.Errorf("unable to parse option x-multi-statement: %w", err)
		}
	}

	px, err := WithInstance(db, &Config{
		DatabaseName:          purl.Path,
		MigrationsTable:       migrationsTable,
		MigrationsTableQuoted: migrationsTableQuoted,
		StatementTimeout:      time.Duration(statementTimeout) * time.Millisecond,
		MultiStatementEnabled: multiStatementEnabled,
		MultiStatementMaxSize: multiStatementMaxSize,
	})

	if err != nil {
		return nil, err
	}

	return px, nil
}

View on GitHub (pinned to 01a9643f14)

Solutions

  1. Change the parameter to a Go-parseable boolean: true, false, 1, or 0
  2. Remove the x-multi-statement parameter entirely if the default (false) is desired
  3. Log the full DSN used and fix the code or env var that interpolates a non-boolean value

Example fix

// before
url := "postgres://u:p@host/db?x-multi-statement=yes"
// after
url := "postgres://u:p@host/db?x-multi-statement=true"
Defensive patterns

Strategy: validation

Validate before calling

v := dsn.Query().Get("x-multi-statement")
if v != "" {
    if _, err := strconv.ParseBool(v); err != nil {
        return fmt.Errorf("x-multi-statement must be a Go-parseable bool, got %q", v)
    }
}

Prevention

When it happens

Trigger: Passing x-multi-statement=yes, x-multi-statement=on, or any other non-boolean string in a postgres:// URL passed to Open/New.

Common situations: Developers accustomed to other libraries' loose boolean parsing ('yes'/'on'/'1'/'enabled') set a truthy value that Go's ParseBool rejects; also happens when generating DSNs programmatically with unset variables producing text like '<nil>' or 'undefined'.

Understand the failure class

Related errors


AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02). Data as JSON: /api/errors/fbd92cd27300ad60. Report an issue: GitHub.