projectdiscovery/nuclei · error

invalid connection string: %v

Error message

invalid connection string: %v

What it means

Returned by the pgwrap Postgres driver's Open when url.Parse fails on the connection string passed to sql.Open. pgwrap wraps pq and expects a URL-style DSN (scheme://user:pass@host:port/db?...) carrying an executionId query parameter that it strips out before delegating to pq.DialOpen. Anything that is not a parseable URL — keyword/value DSNs, spaces, or unencoded special characters — fails here.

Source

Thrown at pkg/js/utils/pgwrap/pgwrap.go:89

	connector.Dialer(&pgDial{executionId: executionId, ctx: ctx})
	return sql.OpenDB(connector), nil
}

// Unfortunately lib/pq does not provide easy to customize or
// replace dialer so we need to hijack it by wrapping it in our own
// driver and register it as postgres driver

// PgDriver is the Postgres database driver.
type PgDriver struct{}

// Open opens a new connection to the database. name is a connection string.
// Most users should only use it through database/sql package from the standard
// library.
func (d PgDriver) Open(name string) (driver.Conn, error) {
	// Parse the connection string to get executionId
	u, err := url.Parse(name)
	if err != nil {
		return nil, fmt.Errorf("invalid connection string: %v", err)
	}
	values := u.Query()
	executionId := values.Get("executionId")
	// Remove executionId from the connection string
	values.Del("executionId")
	u.RawQuery = values.Encode()

	return pq.DialOpen(&pgDial{executionId: executionId}, u.String())
}

func init() {
	sql.Register(PGWrapDriver, &PgDriver{})
}

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Use URL-form DSN: postgres://user:pass@host:5432/dbname?executionId=<id>
  2. URL-encode the password and any values containing reserved characters (use encodeURIComponent in JS or url.URL in Go)
  3. Build the DSN programmatically instead of string concatenation

Example fix

// before
sql.Open('postgreswrap', "postgres://user:p@ss word@db:5432/app?executionId=" + execId);

// after
const dsn = `postgres://user:${encodeURIComponent(password)}@db:5432/app?executionId=${encodeURIComponent(execId)}`;
sql.Open('postgreswrap', dsn);
Defensive patterns

Strategy: validation

Validate before calling

import net/url

func buildDSN(user, pass, host string, port int, db, execID string) (string, error) {
	u := url.URL{Scheme: "postgres", User: url.UserPassword(user, pass), Host: net.JoinHostPort(host, strconv.Itoa(port)), Path: db}
	q := u.Query(); q.Set("executionId", execID); u.RawQuery = q.Encode()
	return u.String(), nil
}

Prevention

When it happens

Trigger: Passing a libpq keyword DSN like 'host=db port=5432 user=...' instead of a URL; unencoded symbols in the password (#, %, @, spaces) breaking the URL grammar; missing scheme; malformed percent-encoding anywhere in the string.

Common situations: Copy-pasting DSNs from pq/psql configs into nuclei' Postgres JS library; passwords generated with URL-reserved characters; forgetting the executionId parameter required by the wrapped driver.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/559840a608865a6d. Report an issue: GitHub.