I am trying to connect to MongoDB from my Go application but getting an error with ReplicaSetNoPrimary.
Here is my code connection to MongoDB:
exmple of MongoDB URI:
mongodb+srv://user:pass@ntw.55n9jaw.mongodb.net/?retryWrites=true&w=majority&appName=ntw
func SetupDB(uri string) *mongo.Client {
log.Printf("Connecting to MongoDB")
log.Printf("URI: %s", uri)
ctx := context.TODO()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
if err != nil {
log.Fatalf("Failed to connect to MongoDB: %v", err)
}
defer func() {
if err := client.Disconnect(ctx); err != nil {
log.Fatalf("Failed to disconnect from MongoDB: %v", err)
}
}()
if err := client.Ping(ctx, readpref.Primary()); err != nil {
log.Fatalf("Failed to ping MongoDB: %v", err)
}
log.Printf("Connected to MongoDB")
return client
}
Here is the error I am getting:
Failed to ping MongoDB: server selection error: server selection timeout, current topology:
{ Type: ReplicaSetNoPrimary,
Servers: [{ Addr: ac-l4ofxbw-shard-00-00.55n9jaw.mongodb.net:27017,
Type: Unknown,
Last error: tls: failed to verify certificate: x509: certificate has expired or is not yet valid: },
{ Addr: ac-l4ofxbw-shard-00-01.55n9jaw.mongodb.net:27017,
Type: Unknown,
Last error: tls: failed to verify certificate: x509: certificate has expired or is not yet valid: },
{ Addr: ac-l4ofxbw-shard-00-02.55n9jaw.mongodb.net:27017,
Type: Unknown,
Last error: tls: failed to verify certificate: x509: certificate has expired or is not yet valid: }, ] }
>Solution :
The error you are encountering, ReplicaSetNoPrimary, indicates that your MongoDB client is unable to find a primary node in the replica set. The specific issue appears to be related to an invalid or expired TLS certificate, as indicated by the errors for each server: tls: failed to verify certificate: x509: certificate has expired or is not yet valid.
Here are a few steps you can take to diagnose and resolve this issue:
-
Check System Time: Ensure that the system time on your machine is
correctly synchronized. Certificate validation relies on the system
time, and if your system time is incorrect, it can cause
certificates to appear expired or not yet valid. -
Verify Certificate Validity: Check the validity of the certificates
used by your MongoDB Atlas cluster. You can do this by accessing the
MongoDB Atlas UI and checking the cluster’s settings. Ensure that
the certificates are valid and not expired.
enter code here -
Update CA Certificates: Ensure that your system has up-to-date
Certificate Authority (CA) certificates. This can usually be done by
updating the ca-certificates package on your system. -
Explicit TLS Configurations: You can configure your MongoDB client
to explicitly trust the provided certificates by specifying the CA
file. This can be done using the tlsCAFile option in your connection
string. Here is an example:
package main
import (
"context"
"crypto/tls"
"crypto/x509"
"io/ioutil"
"log"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
func SetupDB(uri string) *mongo.Client {
log.Printf("Connecting to MongoDB")
log.Printf("URI: %s", uri)
ctx := context.TODO()
// Load CA file
caFilePath := "path/to/ca.pem"
caCert, err := ioutil.ReadFile(caFilePath)
if err != nil {
log.Fatalf("Failed to read CA file: %v", err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig := &tls.Config{
RootCAs: caCertPool,
}
clientOptions := options.Client().ApplyURI(uri).SetTLSConfig(tlsConfig)
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatalf("Failed to connect to MongoDB: %v", err)
}
defer func() {
if err := client.Disconnect(ctx); err != nil {
log.Fatalf("Failed to disconnect from MongoDB: %v", err)
}
}()
if err := client.Ping(ctx, readpref.Primary()); err != nil {
log.Fatalf("Failed to ping MongoDB: %v", err)
}
log.Printf("Connected to MongoDB")
return client
}
func main() {
uri := "mongodb+srv://user:pass@ntw.55n9jaw.mongodb.net/?retryWrites=true&w=majority&appName=ntw"
SetupDB(uri)
}