Configure Aerospike Clients
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
Connect your application to Aerospike Cloud over TLS from a host in your peered AWS VPC. Database endpoints use private addresses reachable only after VPC peering is configured and your VPC is associated with the Aerospike Cloud private hosted zone.
Aerospike Cloud clusters use TLS on port 4000. You cannot configure a different TLS port. Confirm Hostname and TLS port in the Connection section on the Details tab.
This page is the application step after VPC peering and database users. For first-time cluster setup, see the Aerospike Cloud quickstart.
Prerequisites
Before configuring a client, confirm the following:
- VPC peering status is Active in the Aerospike Cloud console and AWS.
- DNS association with the Aerospike Cloud private hosted zone is complete so Hostname resolves to node private IPs. Without it, clients cannot use the console hostname and would need node IPs you cannot look up from the console.
- Route tables and security groups allow outbound TCP
4000to the Aerospike Cloud VPC CIDR (default10.128.0.0/19). See Configure AWS VPC peering for details. - A database user exists with the roles your application needs (for example
read-write). - Your application (or test host) runs inside the peered VPC (for example EC2, EKS worker, Lambda with VPC access).
Configure your client
Before running the examples below, collect the following from the Aerospike Cloud console. All values come from the cluster Details tab unless noted.
| What you need | Where to find it |
|---|---|
<HOSTNAME>: seed address and TLS name (for example a1b2c3d4-e5f6-7890-abcd-ef1234567890.aerospike.internal) | Connection section → Hostname |
TLS port (4000) | Connection section → TLS port |
| CA certificate (PEM) | Certificates section → download or copy TLS certificate |
<DB_USERNAME> / <DB_PASSWORD> | Access manager tab (separate from your Cloud console login) |
<NAMESPACE> | Configuration section → Namespace |
You can also retrieve connection details from the API using Cluster ID from the General section. See Use Cloud APIs for authentication.
curl -s "https://api.aerospike.com/v1/database/clusters/<CLUSTER_ID>" \ -H "Authorization: Bearer <BEARER_TOKEN>" \ | jq '.connectionDetails | {hostname, tlsCertificate: (.tlsCertificate | length)}'Replace <HOSTNAME>, <DB_USERNAME>, <DB_PASSWORD>, and <NAMESPACE> in the examples below with your cluster values.
Aerospike Cloud uses one-way TLS (server certificate verified with the CA). You do not need mutual TLS (mTLS) or a client certificate.
Download the TLS certificate from the Certificates section, then build a TrustStore:
Add CA certificate to Java TrustStore on client nodes
The CA certificate is a public certificate which verifies that the certificate presented by the Aerospike Database is signed by a trusted authority.
Replace all placeholder certificate filenames with the correct filenames for your system.
- The following command imports
example.ca.crtinto a new Java TrustStore namedexample.ca.jks. The new TrustStore will be used exclusively by the intended Java application.
keytool -importcert -storetype jks -alias example.ca \-keystore example.ca.jks -file example.ca.crt \-storepass changeitCreate a strong password
The previous example follows the Java convention of using “changeit” as the password. Change this to a strong password governed by your organization’s password policy.
- Verify the certificate is in the TrustStore with the
keystore -listcommand:
keytool -list -keystore example.ca.jks -storepass changeitKeystore type: jksKeystore provider: SUN
Your keystore contains 1 entry
example.ca, Apr 5, 2022, trustedCertEntry,Certificate fingerprint (SHA1): 85:99:36:F8:20:A7:42:AA:ED:E6:9B:7BThe entry is listed as trustedCertEntry.
This file can be stored on the filesystem with other public certificates.
Truststore Storage
Do not import the CA certificate into the default system-wide TrustStore of trusted CA certificates used by the Java runtime. Default system-wide trusted CA certificates present security issues, and are not allowed by many enterprise security requirements.
-
Connect with TLS on port
4000:import com.aerospike.client.AerospikeClient;import com.aerospike.client.Host;import com.aerospike.client.policy.ClientPolicy;import com.aerospike.client.policy.TlsPolicy;String hostname = "<HOSTNAME>";Host host = new Host(hostname, hostname, 4000);ClientPolicy policy = new ClientPolicy();policy.user = "<DB_USERNAME>";policy.password = "<DB_PASSWORD>";policy.tlsPolicy = new TlsPolicy();AerospikeClient client = new AerospikeClient(policy, host); -
Start the JVM with your TrustStore. The store password must match
keytool -storepass:Terminal window java -Djavax.net.ssl.trustStore=example.ca.jks \-Djavax.net.ssl.trustStorePassword=<STORE_PASSWORD> \-jar your-application.jar
For additional TLS options, see Java client: TLS secured connection.
Use a current Go client module (for example github.com/aerospike/aerospike-client-go/v8).
The Go client does not use the OS trust store by default. Load the Cloud CA from the PEM file you downloaded and add it to a CertPool. Pass the pool as RootCAs in the tls.Config.
NewClientWithPolicyAndHost returns before the cluster handshake completes. Use the IsConnected() poll to wait for readiness, then call WarmUp(0) to pre-establish connections to all nodes before accepting application traffic.
import ( "crypto/tls" "crypto/x509" "log" "os" "time"
as "github.com/aerospike/aerospike-client-go/v8")
hostname := "<HOSTNAME>"caPEM, err := os.ReadFile("/path/to/certificate.pem")if err != nil { log.Fatal(err)}
pool := x509.NewCertPool()if !pool.AppendCertsFromPEM(caPEM) { log.Fatal("unable to parse CA certificate")}
host := as.NewHost(hostname, 4000)host.TLSName = hostname
policy := as.NewClientPolicy()policy.User = "<DB_USERNAME>"policy.Password = "<DB_PASSWORD>"policy.TlsConfig = &tls.Config{RootCAs: pool}
client, err := as.NewClientWithPolicyAndHost(policy, host)if err != nil { log.Fatalf("connect: %v", err)}defer client.Close()
for i := 0; i < 50 && !client.IsConnected(); i++ { time.Sleep(100 * time.Millisecond)}if !client.IsConnected() { log.Fatal("cluster not connected")}
if _, err := client.WarmUp(0); err != nil { log.Fatalf("warmup: %v", err)}Install the client for the Python version you run. If the prebuilt wheel does not include the C client for your platform, set DOWNLOAD_C_CLIENT=1 before installing:
export DOWNLOAD_C_CLIENT=1pip install aerospikeUse the same Python version for install and for your application. See Install the Aerospike Python client for platform-specific prerequisites.
Connect with TLS on port 4000:
import osimport aerospike
hostname = os.environ["AEROSPIKE_HOSTNAME"]
config = { "hosts": [(hostname, 4000, hostname)], "user": os.environ["AEROSPIKE_USER"], "password": os.environ["AEROSPIKE_PASSWORD"], "tls": {"enable": True, "cafile": os.environ["AEROSPIKE_CA"]},}
client = aerospike.client(config).connect()See Python client: TLS secured connection and Install the Aerospike Python client.
Set TlsPolicy on ClientPolicy to enable TLS. Pass <HOSTNAME> as both the seed address and the TLS name, with port 4000. Add your database user credentials on the same policy.
The C# client does not accept a CA file path in TlsPolicy. .NET validates the server certificate against the OS trust store, so install the Cloud CA on the host before you connect.
using Aerospike.Client;
string hostname = "<HOSTNAME>";
Host host = new(hostname, hostname, 4000);
ClientPolicy policy = new(){ user = "<DB_USERNAME>", password = "<DB_PASSWORD>", tlsPolicy = new TlsPolicy(),};
AerospikeClient client = new(policy, host);On Linux, add the Cloud CA to the system trust store:
sudo cp certificate.pem /etc/pki/ca-trust/source/anchors/aerospike-cloud.crtsudo update-ca-trustSee C# client: TLS secured connection and the TlsPolicy API.
Install the Aerospike Node.js client, then create a client with TLS enabled. Set tlsname on each host to <HOSTNAME> (the same value as the seed address). Point tls.cafile at the PEM file you downloaded from the console, and pass database user credentials in the client config. Call connect() before running operations.
const Aerospike = require("aerospike");
async function main() { const hostname = "<HOSTNAME>";
const client = Aerospike.client({ hosts: [{ addr: hostname, port: 4000, tlsname: hostname }], user: "<DB_USERNAME>", password: "<DB_PASSWORD>", tls: { enable: true, cafile: "/path/to/certificate.pem", }, });
await client.connect();}
main().catch(console.error);The Aerospike PHP client does not connect to the database directly. The Go connection manager daemon (asld) maintains the cluster connection. PHP talks to asld over a local Unix socket.
Aerospike Cloud uses one-way TLS. Configure asld with the cluster hostname (<HOSTNAME>), port 4000, the Cloud CA file, and database user credentials. You do not need client certificate files (tls-certfile / tls-keyfile) unless you use mutual TLS.
-
Build and install the PHP client and connection manager on a host in your peered VPC. See Install the Aerospike PHP client for prerequisites (PHP 8.1+, Go, Rust, Protobuf compiler).
-
Edit
asld.tomlin the connection manager directory (for examplephp-client/aerospike-connection-manager/asld.toml):[cluster]socket = "/tmp/asld_grpc.sock"host = "<HOSTNAME>:4000"user = "<DB_USERNAME>"password = "<DB_PASSWORD>"tls-name = "<HOSTNAME>"tls-enable = truetls-cafile = "/path/to/certificate.pem"Use
<HOSTNAME>for bothhostandtls-name. Do not substitute<CLUSTER_ID>. -
Start the connection manager from its directory:
Terminal window cd php-client/aerospike-connection-manager./asld -
In your PHP application, connect to the local socket (not the Aerospike hostname directly):
<?phpnamespace Aerospike;$client = Client::connect("/tmp/asld_grpc.sock");
See PHP client: TLS secured connection and Running your PHP project.
Verify connectivity
Run verification from a host inside your peered VPC (the same network context as your application).
-
Confirm you can resolve the cluster hostname to private IPs. Use the
<HOSTNAME>value from the connection parameters table.Terminal window dig +short <HOSTNAME> -
Run your client with the configuration from the previous section.
-
Write and read a test record (adjust
namespace,set, and key for your cluster).After your client connects, write and read a single record in
<NAMESPACE>. Use a defaultWritePolicyso you do not set a TTL. Add the following to your connect example (imports omitted if already present):import com.aerospike.client.Bin;import com.aerospike.client.Key;import com.aerospike.client.Record;import com.aerospike.client.policy.WritePolicy;Key key = new Key("<NAMESPACE>", "connectivity-test", "ping");client.put(new WritePolicy(), key, new Bin("status", "ok"));Record record = client.get(null, key);System.out.println("Read back: " + record);client.close();After your client connects and
WarmUpcompletes, put a test record withNewWritePolicy(0, 0)so TTL stays at server default, read it back, then optionally delete withDurableDeleteif your cluster uses SC mode.key, err := as.NewKey("<NAMESPACE>", "connectivity-test", "ping")if err != nil {log.Fatalf("new key: %v", err)}wp := as.NewWritePolicy(0, 0) // generation 0, TTL 0 (no expiry)if err := client.Put(wp, key, as.BinMap{"status": "ok"}); err != nil {log.Fatalf("put: %v", err)}rec, err := client.Get(nil, key)if err != nil {log.Fatalf("get: %v", err)}fmt.Println("Read back:", rec.Bins)dp := as.NewWritePolicy(0, 0)dp.DurableDelete = trueif _, err := client.Delete(dp, key); err != nil {log.Fatalf("delete: %v", err)}Use a tuple key with your namespace, set, and user key. Call
putthengeton the connected client. Omit TTL in the write so it matches Cloud defaults for new clusters.key = ("<NAMESPACE>", "connectivity-test", "ping")client.put(key, {"status": "ok"})_, _, bins = client.get(key)print(bins) # expect {'status': 'ok'}client.close()After the client is constructed with TLS and credentials, put and get one record in
<NAMESPACE>. Use a defaultWritePolicyand confirm the read output shows your bin values.Key key = new("<NAMESPACE>", "connectivity-test", "ping");client.Put(new WritePolicy(), key, new Bin("status", "ok"));Record record = client.Get(null, key);Console.WriteLine("Read back: " + record);client.Close();Run this check after
await client.connect(). It writes and reads one record in the namespace from your environment variables. Callverify(client)from yourmain()function.async function verify(client) {const key = new Aerospike.Key(process.env.AEROSPIKE_NAMESPACE,"connectivity-test","ping");await client.put(key, { status: "ok" });const rec = await client.get(key);console.log("Read back:", rec.bins);await client.close();}Run this only after
asldis started with your Cloud TLSasld.toml. The PHP client talks toasldover the local socket, then issues put and get against<NAMESPACE>.$key = new Key("<NAMESPACE>", "connectivity-test", "ping");$client->put(new WritePolicy(), $key, [new Bin("status", "ok")]);$record = $client->get(new ReadPolicy(), $key);var_dump($record->bins);$client->close();If the write succeeds and the read returns your bin values, TLS, RBAC, routing, and DNS are working for application traffic.
If you include a delete in your smoke test and your cluster uses strong consistency (SC) mode, use
DurableDelete(as shown in the Go example above). SC namespaces reject plain deletes. See FAIL_FORBIDDEN on writes.
Troubleshooting
Aerospike Cloud differs from a self-managed cluster in a few ways that affect clients:
- TLS port
4000and Hostname are in the Connection section on the Details tab. Use Hostname (not Cluster ID) as the seed address and TLS name. - Database users are separate from Aerospike Cloud console accounts. Applications authenticate with database user credentials only.
- Record expiration is disabled by default (
nsup-periodis0). Writes that set a TTL can returnFAIL_FORBIDDENuntil you enable record expiration. - Consistency mode is AP or SC, chosen at provisioning. Check Consistency mode in the Configuration section on the Details tab.
If the client cannot connect, use the connection table below. If put, get, or delete return FAIL_FORBIDDEN, see FAIL_FORBIDDEN on writes.
| Symptom | Likely cause | What to check |
|---|---|---|
| Connection timeout | App not in peered VPC, or network misconfiguration | Run tests from EC2/EKS inside your peered VPC. See VPC peering troubleshooting for routing, security group, and DNS checks. |
| DNS failure | Hosted zone not associated with your VPC | Associate the private hosted zone. Confirm DNS hostnames and DNS resolution are enabled on the VPC. |
| TLS handshake failure | Wrong CA file, TLS name, or port | Confirm TLS port is 4000, Hostname is the TLS name, and the CA file is from the Certificates section on the Details tab. |
| Peers not reachable | Client resolves hostname but cannot reach node IPs | Run client inside peered VPC. Confirm security groups allow outbound TCP 4000 to the Aerospike CIDR (10.128.0.0/19 by default). |
FAIL_FORBIDDEN on writes
Write or delete operations can return FAIL_FORBIDDEN: Operation not allowed at this time (error code 22) even when the database user has the correct RBAC roles. The error can look like an RBAC or connectivity issue but is usually caused by one of the following.
The Aerospike server rejects writes that include a time to live (TTL) when the namespace has record expiration disabled. Record expiration is disabled when nsup-period is 0, which is the default for new Aerospike Cloud clusters. The server logs a warning similar to:
WARNING (rw): (write.c::) write_master: disallowed ttl with nsup-period 0To resolve TTL-related failures, choose one of the following:
- Remove the TTL from your client code. If your application does not require record expiration, omit the TTL from write operations (or set it to
0, meaning the record does not expire). - Enable record expiration on the cluster. If your application requires TTLs, set
nsup-periodto a non-zero value in advanced configuration.
In strong consistency (SC) mode, plain deletes (without the durable delete flag) are rejected because they do not produce the tombstone record needed to maintain consistency across nodes. The server requires durable_delete: true on the write policy for any delete operation.
Set DurableDelete (or the equivalent in your client language) on the write policy before calling delete. The Go verify example above shows this pattern. To allow non-durable deletes, set strong-consistency-allow-expunge: true in the namespace configuration, though this is not recommended for production.
What’s next
- Observe metrics from your cluster
- Operational guidelines for production clients (circuit breakers, retries, TLS)
- Advanced configuration for namespace and server settings