googleapis/mcp-toolbox · error

unable to get AlloyDB connection config: %w

Error message

unable to get AlloyDB connection config: %w

What it means

initAlloyDBPgConnectionPool wraps any error returned by getConnectionConfig (credential resolution, DSN construction, invalid ipType/option combination) with this message before the pool can be created. It means the source could not compute a valid connection string for the AlloyDB instance, so pool initialization is aborted. The underlying cause is chained via %w and is the real diagnostic.

Source

Thrown at internal/sources/alloydbpg/alloydb_pg.go:218

	if readOnly {
		// IMPORTANT: Must use underscore ('alloydb_session_read_only'), NOT a dot.
		// PostgreSQL treats dotted GUCs (e.g. 'alloydb.session_read_only') as custom placeholders
		// and silently ignores them at connection time, leaving the session in read-write mode.
		dsn += " options='-c alloydb_session_read_only=locked'"
	}

	return dsn, useIAM, nil
}

func initAlloyDBPgConnectionPool(ctx context.Context, tracer trace.Tracer, name, project, region, cluster, instance, ipType, user, pass, dbname string, readOnly bool) (*pgxpool.Pool, error) {
	//nolint:all // Reassigned ctx
	ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name)
	defer span.End()

	dsn, useIAM, err := getConnectionConfig(ctx, user, pass, dbname, readOnly)
	if err != nil {
		return nil, fmt.Errorf("unable to get AlloyDB connection config: %w", err)
	}

	config, err := pgxpool.ParseConfig(dsn)
	if err != nil {
		return nil, fmt.Errorf("unable to parse connection uri: %w", err)
	}
	// Create a new dialer with options
	userAgent, err := util.UserAgentFromContext(ctx)
	if err != nil {
		return nil, err
	}
	opts, err := getOpts(ipType, userAgent, useIAM)
	if err != nil {
		return nil, err
	}
	d, err := alloydbconn.NewDialer(ctx, opts...)
	if err != nil {
		return nil, fmt.Errorf("unable to parse connection uri: %w", err)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Read the wrapped cause after 'unable to get AlloyDB connection config:' — fix that root cause first.
  2. If using IAM auth (empty user/pass), ensure ADC is configured and the identity can access AlloyDB.
  3. Provide both username and password together, or leave both empty; never provide only a password.
  4. Validate the ipType value (public|private) and network reachability settings in the source config.

Example fix

// before: password without username
{"user": "", "pass": "secret", ...}
// after: supply both
{"user": "appuser", "pass": "secret", ...}
Defensive patterns

Strategy: try-catch

Validate before calling

if (pass == "") != (user == "") {
    return errors.New("provide both user and password, or neither for IAM auth")
}

Try / catch

_, err := initAlloyDBPgConnectionPool(ctx, cfg)
if err != nil {
    var cfgErr *fmt.ConfigError
    if errors.As(err, &cfgErr) { /* fix config */ }
    return fmt.Errorf("pool init failed: %w", err)
}

Prevention

When it happens

Trigger: Calling Initialize on the alloydbpg source when: user/password rules are violated (password without username), ADC email lookup fails (see error 430), the ipType option is invalid, or the UserAgent cannot be derived downstream — any failure inside getConnectionConfig.

Common situations: Typos or bad values in the YAML config (e.g. invalid ipType), half-configured IAM auth (password set but user empty), missing GCP credentials in the deployment environment, or invalid project/region/cluster/instance strings feeding the DSN template.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/1641f4944558cbfd. Report an issue: GitHub.