{"record":{"id":"c63a8ab61e878fff","repo":"argoproj/argo-workflows","slug":"failed-to-open-traced-postgres-connection-w","errorCode":null,"errorMessage":"failed to open traced postgres connection: %w","messagePattern":"failed to open traced postgres connection: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"util/sqldb/sqldb.go","lineNumber":245,"sourceCode":"\t// Build PostgreSQL DSN using url.URL for safe percent-encoding of credentials\n\tconnURL := url.URL{\n\t\tScheme: \"postgres\",\n\t\tUser:   url.UserPassword(username, password),\n\t\tHost:   cfg.GetHostname(),\n\t\tPath:   cfg.Database,\n\t}\n\tquery := url.Values{}\n\tquery.Set(\"sslmode\", postgresSSLMode(cfg))\n\t// connect_timeout limits connection setup (dial + handshake) to ensure fast failure if the DB is unreachable.\n\t// lib/pq resets this deadline afterward, leaving subsequent queries unaffected.\n\tquery.Set(\"connect_timeout\", strconv.Itoa(int(connectTimeout.Seconds())))\n\tconnURL.RawQuery = query.Encode()\n\tdsn := connURL.String()\n\n\t// Create traced *sql.DB using otelsql\n\tsqlDB, err := otelsql.Open(\"postgres\", dsn, otelSQLOptions(semconv.DBSystemNamePostgreSQL, cfg.Database)...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to open traced postgres connection: %w\", err)\n\t}\n\treturn newPostgresSession(sqlDB, persistPool)\n}\n\n// createMySQLDBSessionWithCreds creates MySQL DB session with direct credentials\n// buildMySQLConfig constructs the mysql.Config (DSN inputs) for a MySQL session,\n// using mysql.Config to safely handle special characters in credentials and\n// configuring the connection-establishment (dial) timeout.\n//\n// Start from mysql.NewConfig() rather than a struct literal so the driver\n// defaults are applied — most importantly Loc: time.UTC. When the session was\n// opened from a DSN string, ParseDSN restored those defaults; NewConnector\n// consumes the config directly, so a bare literal would leave Loc nil and\n// panic (\"missing Location in call to Time.In\") on the first time.Time written.\nfunc buildMySQLConfig(cfg *config.MySQLConfig, username, password string, connectTimeout time.Duration) (*mysql.Config, error) {\n\tmysqlCfg := mysql.NewConfig()\n\tmysqlCfg.User = username\n\tmysqlCfg.Passwd = password","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/util/sqldb/sqldb.go#L227-L263","documentation":"This error wraps the failure from otelsql.Open when opening a traced PostgreSQL connection during database session creation in Argo Workflows. otelsql.Open is a pass-through to database/sql's sql.Open plus OpenTelemetry instrumentation; it fails when the driver cannot be found or the DSN/connection string is malformed (sql.Open does not dial yet, so this is usually a DSN/config problem, not a network problem). The underlying driver error is preserved via %w so it can be inspected with errors.Unwrap or errors.As.","triggerScenarios":"CreateDBSessionWithCreds or createPostGresDBSession is called with a PostgresConfig whose DSN is invalid (bad scheme, unparseable host/port or query parameters), or the 'postgres' database/sql driver failed to register (blank import of the pq driver missing at binary build time).","commonSituations":"Misconfigured database section of the workflow-controller configmap (typos in host, port, or connection options); malformed URL-encoded characters in the password embedded into the DSN; custom builds that dropped the pq driver import; upgrading Argo with a changed connection-string format.","solutions":["Read the wrapped cause with errors.Unwrap/`%v` output and fix the reported DSN syntax problem in the Postgres config (host, port, dbname, connection options).","Verify the postgres connection string builds as a valid URL — special characters in username/password must be URL-escaped (e.g. use url.QueryEscape or pass credentials via secrets handling that escapes them).","Ensure the postgres driver is registered in your build (blank import _ \"github.com/lib/pq\") if building custom binaries.","Confirm controller --database-configuration flags / configmap keys match the documented PostgresConfig schema."],"exampleFix":"// before (config with raw special chars in password)\npostgresql:\n  host: db\n  password: p@ss:w0rd   # parsed into DSN unescaped -> parse error\n// after\npostgresql:\n  host: db\n  password: p%40ss%3Aw0rd   # or source from secret, escaped when building DSN","handlingStrategy":"validation","validationCode":"u, err := url.Parse(cfg.Host)\nif err != nil || cfg.Host == \"\" { return fmt.Errorf(\"invalid postgres host/dsn: %w\", err) }\n// also ensure password chars are URL-escaped before building the session\n_ = url.QueryEscape(password)","typeGuard":null,"tryCatchPattern":"session, err := CreateDBSessionWithCreds(ctx)\nif err != nil {\n    var derr error\n    if errors.As(err, &derr) { /* inspect unwrapped driver/DSN error */ }\n    logger.Error(ctx, \"db session creation failed\", err)\n    return err\n}","preventionTips":["URL-escape username/password before they enter the DSN.","Validate the database config schema at controller startup before touching the DB.","Pin and blank-import the pq driver in custom builds.","Keep connection settings in the documented configmap keys only."],"tags":["database","postgres","connection","opentelemetry"],"backgroundTag":"invalid-database-dsn","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}