googleapis/mcp-toolbox · error

unable to connect successfully: %w

Error message

unable to connect successfully: %w

What it means

Wrapped when pool.PingContext fails after the pool was opened successfully — meaning the DSN parsed but an actual round-trip to the Firebird server failed (unreachable host, wrong credentials, database file not found). Initialize closes the pool before returning this error.

Source

Thrown at internal/sources/firebird/firebird.go:71

	User     string `yaml:"user" validate:"required"`
	Password string `yaml:"password" validate:"required"`
	Database string `yaml:"database" validate:"required"`
}

func (r Config) SourceConfigType() string {
	return SourceType
}

func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
	pool, err := initFirebirdConnectionPool(ctx, tracer, r.Name, r.Host, r.Port, r.User, r.Password, r.Database)
	if err != nil {
		return nil, fmt.Errorf("unable to create pool: %w", err)
	}

	err = pool.PingContext(ctx)
	if err != nil {
		pool.Close()
		return nil, fmt.Errorf("unable to connect successfully: %w", err)
	}

	s := &Source{
		Config: r,
		Db:     pool,
	}
	return s, nil
}

var _ sources.Source = &Source{}

type Source struct {
	Config
	Db *sql.DB
}

func (s *Source) IsReadOnly() bool {
	return false

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Verify the Firebird server is listening (telnet/nc host 3050)
  2. Validate credentials with isql or flamerobin using the same user/password/database
  3. Check the database file path exists as seen from the SERVER, not the client
  4. Increase the context timeout if the server is slow to accept connections

Example fix

// before
err = pool.PingContext(ctx)
if err != nil {
    pool.Close()
    return nil, fmt.Errorf("unable to connect successfully: %w", err)
}
// after
ctxPing, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
if err := pool.PingContext(ctxPing); err != nil {
    pool.Close()
    return nil, fmt.Errorf("unable to connect successfully (host=%s:%s): %w", r.Host, r.Port, err)
}
Defensive patterns

Strategy: retry

Validate before calling

// Check TCP reachability before Initialize
conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), 5*time.Second)
if err != nil { return fmt.Errorf("firebird server unreachable: %w", err) }
conn.Close()

Type guard

func isAuthFailure(err error) bool {
    s := err.Error()
    return strings.Contains(s, "Your user name and password are not defined") || strings.Contains(s, "login")
}

Try / catch

if err := pool.PingContext(ctx); err != nil {
    pool.Close()
    if isAuthFailure(err) {
        return nil, fmt.Errorf("firebird credentials rejected: %w", err)
    }
    // transient network errors may be retried with backoff
    return nil, fmt.Errorf("unable to connect successfully: %w", err)
}

Prevention

When it happens

Trigger: Initialize called and PingContext returns: server down/firewalled, wrong user/password, database path does not exist on the server, or ctx deadline exceeded before the handshake completes.

Common situations: Firebird service not running on port 3050; credentials rotated without updating config; relative vs absolute .fdb path confusion between client and server; Docker network isolation; slow embedded startup exceeding context deadline.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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