---
title: "Connecting"
description: "Learn how to connect to Aerospike using the Rust client, including seed node configuration, TLS, and full code examples."
---

# Connecting

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

To connect to an Aerospike database, create a new `Client` instance that specifies the IP address and port of one or more seed nodes in the cluster.

## Single seed node

The client first connects to a seed node, and then discovers the rest of the cluster.

```rust
extern crate aerospike;

use aerospike::{Client, ClientPolicy};

let client = Client::new(&ClientPolicy::default(), &"127.0.0.1:3000".to_string()).await?;
```

> 📖 **API reference**: [`Client::new`](https://docs.rs/aerospike/latest/aerospike/struct.Client.html#method.new)

The port number can be omitted; the client will default to port number 3000.

## Multiple seed nodes

Multiple seed nodes can also be provided. The client iterates through the array of nodes until it successfully connects to a node. It then discovers all nodes in the cluster.

```rust
extern crate aerospike;

use aerospike::{Client, ClientPolicy};

let client = Client::new(&ClientPolicy::default(), "10.0.10.1,10.0.10.2,10.0.10.3").await?;
```

> 📖 **API reference**: [`Client::new`](https://docs.rs/aerospike/latest/aerospike/struct.Client.html#method.new)

## TLS connection without client authentication

Connect to an Aerospike cluster with TLS but without client certificate authentication:

```rust
use std::fs::File;

use std::io::BufReader;

use aerospike::{Client, ClientPolicy, Error};

use rustls::RootCertStore;

use rustls::pki_types::CertificateDer;

fn tls_config_no_client_auth(ca_cert_path: &str) -> Result<rustls::ClientConfig, Error> {

    let mut root_store = RootCertStore::empty();

    let cert_file = File::open(ca_cert_path)

        .map_err(|e| Error::ClientError(format!("Cannot open CA file: {e}")))?;

    let mut reader = BufReader::new(cert_file);

    let certs: Vec<CertificateDer<'static>> = rustls_pemfile::certs(&mut reader)

        .collect::<Result<Vec<_>, _>>()

        .map_err(|e| Error::ClientError(format!("Failed to parse CA certs: {e}")))?;

    root_store.add_parsable_certificates(certs);

    Ok(rustls::ClientConfig::builder()

        .with_root_certificates(root_store)

        .with_no_client_auth())

}

let mut policy = ClientPolicy::default();

policy.tls_config = Some(tls_config_no_client_auth("/path/to/ca-cert.pem")?);

let hosts = "tls-cluster.example.com:4333";

let client = Client::new(&policy, &hosts).await?;
```

> 📖 **API reference**: [`Client::new()`](https://docs.rs/aerospike/latest/aerospike/struct.Client.html#method.new) | [`Error`](https://docs.rs/aerospike/latest/aerospike/enum.Error.html)

## TLS connection with client authentication

Connect to an Aerospike cluster with TLS and mutual authentication using client certificates:

```rust
use std::fs::File;

use std::io::BufReader;

use aerospike::{Client, ClientPolicy, Error};

use rustls::RootCertStore;

use rustls::pki_types::{CertificateDer, PrivateKeyDer};

fn tls_config_with_client_auth(

    ca_cert_path: &str,

    client_cert_path: &str,

    client_key_path: &str,

) -> Result<rustls::ClientConfig, Error> {

    let mut root_store = RootCertStore::empty();

    let cert_file = File::open(ca_cert_path)

        .map_err(|e| Error::ClientError(format!("Cannot open CA file: {e}")))?;

    let mut reader = BufReader::new(cert_file);

    let certs: Vec<CertificateDer<'static>> = rustls_pemfile::certs(&mut reader)

        .collect::<Result<Vec<_>, _>>()

        .map_err(|e| Error::ClientError(format!("Failed to parse CA certs: {e}")))?;

    root_store.add_parsable_certificates(certs);

    let client_cert = CertificateDer::from_pem_file(client_cert_path)

        .expect("Cannot open client certificate file");

    let client_key = PrivateKeyDer::from_pem_file(client_key_path)

        .expect("Cannot open client key file");

    rustls::ClientConfig::builder()

        .with_root_certificates(root_store)

        .with_client_auth_cert(vec![client_cert], client_key)

        .expect("Failed to configure client authentication")

}

let mut policy = ClientPolicy::default();

policy.tls_config = Some(tls_config_with_client_auth(

    "/path/to/ca-cert.pem",

    "/path/to/client-cert.pem",

    "/path/to/client-key.pem",

)?);

let hosts = "tls-cluster.example.com:4333";

let client = Client::new(&policy, &hosts).await?;
```

> 📖 **API reference**: [`Client::new()`](https://docs.rs/aerospike/latest/aerospike/struct.Client.html#method.new) | [`Error`](https://docs.rs/aerospike/latest/aerospike/enum.Error.html)

**Note**: To use TLS features, enable the `tls` feature in your `Cargo.toml`:

```toml
[dependencies]

aerospike = { version = "...", features = ["tls"] }
```

## Maintenance thread

The AerospikeClient constructor creates a maintenance thread that periodically pings nodes for cluster status. If a network disturbance is detected and the client can’t reach any nodes, the seed nodes are used until client-server connection is reestablished.

The Aerospike Client instance is thread-safe and can be used concurrently. Most get/set calls are asynchronous and therefore non-blocking. However, you can use `await` or various tools found in, e.g., Tokio to synchronize code. Connections are cached with a connection pool for each server node.

## Cleanup

When all commands complete and the application is prepared for a clean shutdown, call the `close()` method to remove resources held by the Client instance.

```rust
client.close().await?;
```

> 📖 **API reference**: [`Client::close`](https://docs.rs/aerospike/latest/aerospike/struct.Client.html#method.close)

::: note
The `Client` instance cannot be used after calling `close()`.
:::

## Complete example

In your `Cargo.toml` file:

```txt
[package]

name = "aerospike_connect_create_close"

version = "0.1.0"

edition = "2021"

[dependencies]

aerospike = "2.0.0"

tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```

In your `src/main.rs` file:

```rust
use aerospike::{

    as_bin, as_key,

    policy::RecordExistsAction,

    Client, ClientPolicy, WritePolicy,

};

#[tokio::main]

async fn main() -> Result<(), Box<dyn std::error::Error>> {

    // Connect to localhost Aerospike node (default port 3000).

    let client = Client::new(&ClientPolicy::default(), &"127.0.0.1:3000").await?;

    // Create a new record in namespace "test".

    let key = as_key!("test", "demo", "example-key-1");

    let bin1 = as_bin!("message", "hello from rust");

    let bin2 = as_bin!("count", 1);

    let mut write_policy = WritePolicy::default();

    // Enforce "create only" semantics: fail if record already exists.

    write_policy.record_exists_action = RecordExistsAction::CreateOnly;

    client.put(&write_policy, &key, &vec![bin1, bin2]).await?;

    println!("Record created successfully.");

    // Close client connection cleanly.

    client.close().await?;

    println!("Client closed.");

    Ok(())

}
```

> 📖 **API reference**: [`Client::new`](https://docs.rs/aerospike/latest/aerospike/struct.Client.html#method.new) | [`Client::put`](https://docs.rs/aerospike/latest/aerospike/struct.Client.html#method.put) | [`Client::close`](https://docs.rs/aerospike/latest/aerospike/struct.Client.html#method.close)

Run the example with `cargo run`.

### Expected output

```txt
Record created successfully.

Client closed.
```

## Next steps

Usage examples

Ready for more code examples? We have usage examples for all the basic CRUD operations.

[Usage examples →](https://aerospike.com/docs/develop/client/rust/usage/atomic/create)

Error handling

Actionable errors with recovery suggestions. Know exactly what went wrong and how to fix it.

[Error handling →](https://aerospike.com/docs/develop/client/rust/error-handling)