argoproj/argo-workflows · critical

insufficient authentication information provided

Error message

insufficient authentication information provided

What it means

SessionProxy.connect dispatches on which credentials are present: Kubernetes-secret auth (kubectlConfig+namespace+dbConfig) or direct credentials (username+password+dbConfig). If none of the switch cases match, it returns "insufficient authentication information provided". The SessionProxy was built without enough information to authenticate to the database.

Source

Thrown at util/sqldb/session.go:184

			return fn(newSp)
		}, opts)
	})
}

func (sp *SessionProxy) connect(ctx context.Context) error {
	var sess db.Session
	var err error

	switch {
	case sp.kubectlConfig != nil && sp.namespace != "" && sp.dbConfig != nil:
		// Use Kubernetes secrets for authentication
		sess, _, err = CreateDBSession(ctx, sp.kubectlConfig, sp.namespace, *sp.dbConfig)
	case sp.username != "" && sp.password != "" && sp.dbConfig != nil:
		// Use direct credentials
		sess, _, err = CreateDBSessionWithCreds(*sp.dbConfig, sp.username, sp.password)
	default:
		return fmt.Errorf("insufficient authentication information provided")
	}

	if err != nil {
		return err
	}

	err = sess.Ping()
	if err != nil {
		return err
	}
	sp.closed = false

	sp.sess = sess
	return nil
}

func (sp *SessionProxy) isNetworkError(err error) bool {
	if err == nil {

View on GitHub (pinned to 35bff19146)

Solutions

  1. Provide a complete auth path: set DBConfig plus either (KubectlConfig and Namespace) for secret-based auth, or both Username and Password for direct auth.
  2. Check for partial credentials: an empty Password with a set Username (or vice versa) still falls through — fill both or clear both.
  3. Ensure DBConfig is actually populated (non-nil pointer in the proxy) before calling NewSessionProxy.
  4. If using secret-based auth, load the kubeconfig client and set the namespace where the DB secret lives.
  5. Add pre-call validation of SessionProxyConfig fields to catch this before hitting connect().

Example fix

// before
SessionProxyConfig{DBConfig: cfg, Username: "argo"} // password empty
// after
SessionProxyConfig{DBConfig: cfg, Username: "argo", Password: os.Getenv("PGPASSWORD")}
Defensive patterns

Strategy: validation

Validate before calling

func hasAuthInfo(c SessionProxyConfig) bool {
    secretPath := c.KubectlConfig != nil && c.Namespace != ""
    directPath := c.Username != "" && c.Password != ""
    return (secretPath || directPath) && c.DBConfig != nil
}

Type guard

func hasDirectCreds(c SessionProxyConfig) bool {
    return c.Username != "" && c.Password != ""
}

Try / catch

if !hasAuthInfo(cfg) {
    return fmt.Errorf("refusing to connect: neither secret-based nor direct credentials configured")
}
if _, err := NewSessionProxy(ctx, cfg); err != nil {
    if strings.Contains(err.Error(), "insufficient authentication information") {
        log.Fatal("DB auth config incomplete: set kubectlConfig+namespace OR username+password")
    }
    return err
}

Prevention

When it happens

Trigger: connect() hits the default branch when SessionProxyConfig lacks both (KubectlConfig && Namespace && DBConfig) and (Username && Password && DBConfig) — e.g. DBConfig nil, or username/password partially empty (one of the two set, the other blank), or kubectlConfig nil with empty namespace.

Common situations: Constructing SessionProxyConfig in tests/tools with only Username but empty Password; calling NewSessionProxy without a DBConfig; SessionProxyFromConfig passing an empty DBConfig struct pointer logic mismatch; forgetting to load the kubeconfig so kubectlConfig is nil and namespace empty.

Understand the failure class

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/0bf2022e5ea29327. Report an issue: GitHub.