Neo4jDatabase API Reference¶
The Neo4jDatabase Custom Resource Definition (CRD) provides declarative database management for both Neo4j Enterprise clusters and standalone deployments.
Overview¶
- API Version:
neo4j.neo4j.com/v1beta1 - Kind:
Neo4jDatabase - Supported Neo4j Versions: 5.26.0+ (semver) and 2025.01.0+ (calver)
- Target Deployments: Both
Neo4jEnterpriseClusterandNeo4jEnterpriseStandalone - Database Creation: Automated database provisioning with topology control
- Schema Management: Initial data import and schema creation
- Seed URI Support: Create databases from existing backups (Neo4j 5.26+)
Key Features¶
Universal Compatibility: Works with both cluster and standalone deployments through automatic resource discovery:
- Cluster Support: Create databases across multiple servers with custom topology
- Standalone Support: Create databases in single-node deployments
- Automatic Discovery: Controller automatically detects target deployment type
- Unified API: Same resource definition works for both deployment types
- Topology Control: Specify primary/secondary distribution for cluster databases
- Seed URI: Create databases from S3, GCS, Azure, HTTP, or FTP backup sources
Related Resources¶
Neo4jEnterpriseCluster- Target cluster deploymentsNeo4jEnterpriseStandalone- Target standalone deploymentsNeo4jBackup- Create backups of databasesNeo4jRestore- Restore databases from backupsNeo4jPlugin- Install plugins for database functionality
Spec¶
| Field | Type | Description |
|---|---|---|
clusterRef |
string |
Required. Name of the target Neo4jEnterpriseCluster or Neo4jEnterpriseStandalone in the same namespace. For databases on a Neo4j Aura instance, use the AuraDatabase CRD instead. |
name |
string |
Required. Database name to create. Must start with a letter, contain only letters, digits, dots and dashes, and be 3 to 63 characters long, as Neo4j requires. system is reserved; neo4j is allowed with a warning (it shadows the default database) |
wait |
boolean |
Wait for database creation to complete (default: true) |
ifNotExists |
boolean |
Create only if database doesn't exist - prevents reconciliation errors (default: true) |
topology |
DatabaseTopology |
Database distribution topology (cluster only; ignored, with a warning, for a standalone target). Applied at CREATE DATABASE only — an existing database is observed, not altered |
defaultCypherLanguage |
string (enum: "5", "25") |
Default Cypher language for the database, set at creation with DEFAULT LANGUAGE CYPHER <n>. CalVer only — the clause does not exist on the 5.26 LTS, so the value is checked against the target's image: on the LTS "25" is rejected by validation (spec.defaultCypherLanguage), and "5" is accepted but has no effect (every LTS database already runs Cypher 5, and the clause is omitted from CREATE DATABASE). On CalVer it is applied on every create path — plain, with topology, from a seedURI, or both. Unset, the database takes the server default (spec.serverDefaultCypherLanguage on the deployment) |
options |
map[string]string |
Additional CREATE DATABASE options. The validator accepts only these keys: txLogEnrichment (OFF or DIFF), storeFormat (standard, high_limit or block), existingData (use or fail), existingDataSeedServer, existingDataSeedInstance, existingMetadata, seedCredentials, and seedURI / seedConfig (the last two are deprecated as options — use the dedicated spec fields). Any other key is rejected, and values may not be empty |
initialData |
InitialDataSpec |
Cypher statements run once after creation (mutually exclusive with seedURI). Only cypherStatements is executed |
seedURI |
string |
Backup URI for database creation (mutually exclusive with initialData) |
seedConfig |
SeedConfiguration |
Advanced seed URI configuration |
seedCredentials |
SeedCredentials |
Seed URI access credentials |
DatabaseTopology¶
Cluster-Only Feature: Database topology is only applicable to Neo4jEnterpriseCluster deployments. Ignored for standalone deployments.
| Field | Type | Description |
|---|---|---|
primaries |
int32 |
Number of primary servers. Optional; when set, minimum is 1 |
secondaries |
int32 |
Number of secondary servers (minimum: 0) |
Validation:
primaries + secondariesmust not exceed cluster'sspec.topology.servers- Servers are selected based on role constraints (if configured)
- For standalone deployments, topology is ignored: validation emits a warning, the controller sends no
TOPOLOGYclause, andprimaries: 0is not an error there (on a cluster it is, because a database needs at least one primary) - Topology is applied when the database is created. Editing it on an existing database has no effect — the operator does not issue
ALTER DATABASE … SET TOPOLOGY
InitialDataSpec¶
| Field | Type | Description |
|---|---|---|
source |
string |
Source type for initial data: "cypher", "dump", "csv". Accepted but not acted on — the controller does not read it. A ValidationWarning event is raised when it is set to "dump" or "csv"; "cypher" (what cypherStatements does) is not warned about |
cypherStatements |
[]string |
Cypher statements to execute, in order, against the new database. The only field that is executed. Runs once; status.dataImported records that it has run |
configMapRef |
string |
Accepted but not acted on — the ConfigMap is never read, so put statements in cypherStatements. A ValidationWarning event is raised when it is set. |
secretRef |
string |
Accepted but not acted on. A ValidationWarning event is raised when it is set. |
storage |
*StorageLocation |
Accepted but not acted on (the StorageLocation tables below describe the schema only). A ValidationWarning event is raised when it is set. |
SeedConfiguration¶
Advanced configuration for creating databases from seed URIs using Neo4j's CloudSeedProvider.
| Field | Type | Description |
|---|---|---|
restoreUntil |
string |
Point-in-time recovery timestamp (Neo4j 2025.x only; rejected on 5.26) |
config |
map[string]string |
Seed-provider configuration, rendered into the seedConfig OPTIONS string as comma-separated key=value pairs (for example region=eu-west-1). Consumed by the S3SeedProvider; the CloudSeedProvider (the default for s3://, gs:// and azb://) takes region and credentials from the environment, so most deployments leave this empty |
Point-in-Time Recovery Formats (Neo4j 2025.x only):
- RFC3339 Timestamp:
"2025-01-15T10:30:00Z" - Transaction ID:
"txId:12345"(a positive integer that fits in int64)
config rules: keys may contain only letters, digits, ., _ and -; values may not contain ,, =, quotes, backticks or newlines. The operator forwards the pairs to Neo4j unchanged and does not define any keys of its own — see the Neo4j documentation for the keys your seed provider understands.
SeedCredentials¶
| Field | Type | Description |
|---|---|---|
secretRef |
string |
Name of Kubernetes secret containing credentials for seed URI access |
The Secret must be projected onto the server pods. The Neo4j JVM reads the credentials from its environment, so the Secret has to appear in the target Neo4jEnterpriseCluster/Neo4jEnterpriseStandalone spec.extraEnvFrom. If it does not, the database stays blocked with reason SeedCredsMissing and a message showing what to add. If the target carries the annotation neo4j.com/auto-inherit-seed-creds: "true", the operator appends the entry to spec.extraEnvFrom itself (reason SeedCredsAutoInherited) — this triggers a rolling restart of the target. Omit seedCredentials entirely when you rely on IAM roles / workload identity.
StorageLocation¶
StorageLocationand the tables below are only reachable throughinitialData.storage, which is currently accepted but not acted on.
| Field | Type | Description |
|---|---|---|
type |
string (enum: "s3", "gcs", "azure", "pvc") |
Required. Storage type |
bucket |
string |
Bucket name (for cloud storage) |
path |
string |
Path within bucket or PVC |
pvc |
*PVCSpec |
PVC configuration (for pvc type) |
cloud |
*CloudBlock |
Cloud provider configuration |
PVCSpec¶
| Field | Type | Description |
|---|---|---|
name |
string |
Name of existing PVC to use |
storageClassName |
string |
Storage class name |
size |
string |
Size for new PVC (e.g., "100Gi") |
CloudBlock¶
| Field | Type | Description |
|---|---|---|
provider |
string (enum: "aws", "gcp", "azure") |
Cloud provider |
identity |
*CloudIdentity |
Cloud identity configuration |
credentialsSecretRef |
string |
Name of a Kubernetes Secret with cloud provider credentials as env vars. Optional when using workload identity / IAM instance profiles |
endpointURL |
string |
Overrides the S3 API endpoint URL to target S3-compatible stores (MinIO, Ceph RGW, Cloudflare R2). Only applies to the aws provider |
forcePathStyle |
boolean |
Forces S3 path-style addressing (bucket in URL path). Required for MinIO and most self-hosted S3-compatible stores. Only effective when endpointURL is set |
CloudIdentity¶
| Field | Type | Description |
|---|---|---|
provider |
string (enum: "aws", "gcp", "azure") |
Required. Identity provider |
serviceAccount |
string |
Reserved — accepted but not acted on. Backup/restore Jobs always run as the operator-managed ServiceAccounts |
autoCreate |
*AutoCreateSpec |
Workload-identity annotations (see below) |
AutoCreateSpec¶
| Field | Type | Description |
|---|---|---|
enabled |
bool |
Reserved — accepted but not acted on (the operator always ensures its backup/restore ServiceAccount exists). Schema default: true |
annotations |
map[string]string |
Annotations applied to the operator-managed backup/restore ServiceAccount (used by Neo4jBackup/Neo4jRestore; Neo4jDatabase itself does not read initialData.storage) |
Required Secret Keys by URI Scheme¶
Amazon S3 (s3://):
AWS_ACCESS_KEY_ID(required)AWS_SECRET_ACCESS_KEY(required)AWS_SESSION_TOKEN(optional, for temporary credentials)AWS_REGION(optional)
Google Cloud Storage (gs://):
GOOGLE_APPLICATION_CREDENTIALS(required, service account JSON key)GOOGLE_CLOUD_PROJECT(optional)
Azure Blob Storage (azb://):
AZURE_STORAGE_ACCOUNT(required)- Either
AZURE_STORAGE_KEYorAZURE_STORAGE_SAS_TOKEN(required)
HTTP/HTTPS/FTP:
USERNAME(optional)PASSWORD(optional)AUTH_HEADER(optional, for custom authentication)
Status¶
| Field | Type | Description |
|---|---|---|
conditions |
[]metav1.Condition |
Current status conditions |
phase |
string |
Current phase of the database: Ready, Pending (target not found / not ready), Failed (connection, creation or data-import failure), ValidationFailed, or Unknown (any other blocked state, e.g. SeedCredsMissing) |
message |
string |
Human-readable status message |
observedGeneration |
int64 |
Generation observed by the controller |
dataImported |
*bool |
Whether initial data has been imported |
creationTime |
*metav1.Time |
When the database was created |
size |
string |
Database size |
state |
string |
Current database state: "online", "offline", "started", "stopped" |
servers |
[]string |
Servers hosting the database |
Examples¶
Basic Database in Cluster¶
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: cluster-database
spec:
clusterRef: my-cluster # References Neo4jEnterpriseCluster
name: mydb
wait: true
ifNotExists: true
topology:
primaries: 2 # Distribute across 2 primary servers
secondaries: 1 # 1 secondary for read scaling
Basic Database in Standalone¶
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: standalone-database
spec:
clusterRef: my-standalone # References Neo4jEnterpriseStandalone
name: mydb
wait: true
ifNotExists: true
# Note: topology not needed for standalone (ignored if specified)
Database with Advanced Topology (Cluster Only)¶
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: distributed-database
spec:
clusterRef: production-cluster # Must be Neo4jEnterpriseCluster
name: distributed
wait: true
ifNotExists: true
topology:
primaries: 3 # Uses 3 servers for primary role
secondaries: 2 # Uses 2 servers for secondary role
options:
txLogEnrichment: "DIFF" # Enhanced transaction logging
defaultCypherLanguage: "25" # CalVer only — rejected on the 5.26 LTS
Multi-Database Setup¶
# User-facing database with high availability
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: user-database
spec:
clusterRef: production-cluster
name: users
topology:
primaries: 3
secondaries: 1
initialData:
source: cypher
cypherStatements:
- "CREATE CONSTRAINT user_email IF NOT EXISTS FOR (u:User) REQUIRE u.email IS UNIQUE"
- "CREATE INDEX user_name IF NOT EXISTS FOR (u:User) ON (u.name)"
---
# Analytics database optimized for reads
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: analytics-database
spec:
clusterRef: production-cluster
name: analytics
topology:
primaries: 1 # Minimal write capacity
secondaries: 4 # Optimized for read scaling
options:
txLogEnrichment: "OFF" # Reduce overhead for analytics
Database with Schema and Sample Data¶
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: app-database
spec:
clusterRef: my-cluster # Works with cluster or standalone
name: appdb
wait: true
ifNotExists: true
initialData:
source: cypher
cypherStatements:
# Schema creation
- "CREATE CONSTRAINT user_email IF NOT EXISTS FOR (u:User) REQUIRE u.email IS UNIQUE"
- "CREATE INDEX user_name IF NOT EXISTS FOR (u:User) ON (u.name)"
- "CREATE INDEX product_category IF NOT EXISTS FOR (p:Product) ON (p.category)"
# Sample data
- "CREATE (u:User {name: 'Alice', email: 'alice@example.com'})"
- "CREATE (p:Product {name: 'Neo4j Enterprise', category: 'Database'})"
- "MATCH (u:User {name: 'Alice'}), (p:Product {name: 'Neo4j Enterprise'}) CREATE (u)-[:PURCHASED]->(p)"
topology: # Only applied if clusterRef is a cluster
primaries: 2
secondaries: 1
Neo4j 2025.x Database with Enhanced Features¶
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: modern-database
spec:
clusterRef: neo4j-2025-cluster # Neo4j 2025.x cluster
name: moderndb
wait: true
ifNotExists: true
defaultCypherLanguage: "25" # Enable Cypher 25 features (CalVer only)
topology:
primaries: 2
secondaries: 1
options:
txLogEnrichment: "DIFF" # One of the few keys the validator accepts (see `options` above)
initialData:
source: cypher
cypherStatements:
# Use Cypher 25 syntax features
- "CREATE VECTOR INDEX document_embedding IF NOT EXISTS FOR (d:Document) ON d.embedding OPTIONS {dimension: 1536, similarity: 'cosine'}"
- "CREATE (d:Document {title: 'Neo4j 2025 Guide', embedding: [0.1, 0.2, 0.3]})"
Database from Seed URI (Production Restore)¶
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: prod-restore-database
spec:
clusterRef: recovery-cluster # Target cluster for restore
name: restored-sales-db
# Restore from S3 backup (system-wide IAM authentication)
seedURI: "s3://prod-neo4j-backups/sales-database-2025-01-15.backup"
# Production topology
topology:
primaries: 3 # High availability
secondaries: 2 # Read scaling
# Neo4j 2025.x point-in-time recovery
seedConfig:
restoreUntil: "2025-01-15T10:30:00Z" # Specific point in time
config:
region: "us-east-1" # S3SeedProvider key (rendered as seedConfig "region=us-east-1")
wait: true
ifNotExists: true
defaultCypherLanguage: "25" # CalVer only
options:
txLogEnrichment: "DIFF" # Enhanced logging for production
Database from Seed URI (Development Copy)¶
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: dev-copy-database
spec:
clusterRef: dev-standalone # Can target standalone for development
name: dev-copy
# Copy from Google Cloud Storage backup
seedURI: "gs://dev-backups/prod-snapshot-2025-01-15.backup"
# Explicit credentials for dev environment (the Secret must be in the target's
# spec.extraEnvFrom, or the target needs the neo4j.com/auto-inherit-seed-creds annotation)
seedCredentials:
secretRef: gcs-dev-credentials
wait: true
ifNotExists: true
# No topology needed for standalone deployment
Multi-Cloud Seed URI Examples¶
# AWS S3 with explicit credentials
apiVersion: v1
kind: Secret
metadata:
name: s3-credentials
type: Opaque
data:
AWS_ACCESS_KEY_ID: <base64-encoded-access-key>
AWS_SECRET_ACCESS_KEY: <base64-encoded-secret-key>
AWS_REGION: dXMtZWFzdC0x # us-east-1
---
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: s3-restore-db
spec:
clusterRef: prod-cluster
name: s3-restored
seedURI: "s3://prod-backups/full-backup-2025-01-15.backup"
seedCredentials:
secretRef: s3-credentials
topology:
primaries: 2
secondaries: 1
---
# Google Cloud Storage with service account
apiVersion: v1
kind: Secret
metadata:
name: gcs-credentials
type: Opaque
data:
GOOGLE_APPLICATION_CREDENTIALS: <base64-encoded-service-account-json>
GOOGLE_CLOUD_PROJECT: <base64-encoded-project-id>
---
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: gcs-restore-db
spec:
clusterRef: test-cluster
name: gcs-restored
seedURI: "gs://test-backups/snapshot-2025-01-15.backup"
seedCredentials:
secretRef: gcs-credentials
---
# Azure Blob Storage with SAS token
apiVersion: v1
kind: Secret
metadata:
name: azure-credentials
type: Opaque
data:
AZURE_STORAGE_ACCOUNT: <base64-encoded-account-name>
AZURE_STORAGE_SAS_TOKEN: <base64-encoded-sas-token>
---
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: azure-restore-db
spec:
clusterRef: azure-cluster
name: azure-restored
seedURI: "azb://backups/neo4j-backup-2025-01-15.backup"
seedCredentials:
secretRef: azure-credentials
---
# HTTP/HTTPS with basic authentication
apiVersion: v1
kind: Secret
metadata:
name: http-credentials
type: Opaque
data:
USERNAME: <base64-encoded-username>
PASSWORD: <base64-encoded-password>
---
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: http-restore-db
spec:
clusterRef: local-cluster
name: http-restored
seedURI: "https://backup-server.example.com/backups/neo4j-2025-01-15.backup"
seedCredentials:
secretRef: http-credentials
Advanced Database Management¶
# Asynchronous database creation
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: async-database
spec:
clusterRef: my-cluster
name: asyncdb
wait: false # Returns immediately (NOWAIT mode)
ifNotExists: true
topology:
primaries: 1
secondaries: 0
---
# Initial data: only initialData.cypherStatements is executed (configMapRef,
# secretRef, source and storage are accepted but not acted on), so put every
# statement inline, one per list item
apiVersion: neo4j.neo4j.com/v1beta1
kind: Neo4jDatabase
metadata:
name: complex-database
spec:
clusterRef: my-cluster
name: complex-app
initialData:
cypherStatements:
- "CREATE CONSTRAINT user_id IF NOT EXISTS FOR (u:User) REQUIRE u.id IS UNIQUE"
- "CREATE CONSTRAINT product_sku IF NOT EXISTS FOR (p:Product) REQUIRE p.sku IS UNIQUE"
- "CREATE (u:User {id: 1, name: 'Alice', email: 'alice@example.com'})"
- "CREATE (p:Product {sku: 'NEO4J-ENT', name: 'Neo4j Enterprise'})"
topology:
primaries: 2
secondaries: 1
Behavior¶
Target Discovery¶
Automatic Resource Discovery: The controller automatically determines the target deployment type:
- Cluster Lookup: First attempts to find
Neo4jEnterpriseClusterwith matching name - Standalone Fallback: If cluster not found, looks for
Neo4jEnterpriseStandalone - Validation: Applies appropriate validation rules based on target type
- Client Creation: Uses correct Neo4j client (cluster vs standalone connection)
Default Database (neo4j)¶
Neo4j automatically creates a default database called neo4j at cluster bootstrap with a topology of 1 primary and 0 secondaries. The operator does not create or manage this database.
If you create a Neo4jDatabase resource with name: neo4j, the operator will:
- Emit a validation warning:
'neo4j' is the default database name; creating a database with this name will shadow the default database - Skip creation: Since
ifNotExists: trueis the default and the database already exists,CREATE DATABASEis a no-op - Not alter topology:
topologyis applied atCREATE DATABASEonly. Becauseneo4jalready exists, atopologyon the CR is not applied; change it yourself withALTER DATABASE neo4j SET TOPOLOGY … - Drop on deletion: If you delete the
Neo4jDatabaseresource, the operator will drop theneo4jdatabase — use caution
To control the default database topology at cluster creation time without using this CRD, set initial.dbms.default_primaries_count and initial.dbms.default_secondaries_count in the cluster's spec.config (bootstrap-only, see Clustering Guide).
Database Creation Process¶
Standard Database Creation:
- Discover target deployment (cluster or standalone)
- Check if database exists (if
ifNotExists: true) - Validate topology constraints (cluster only)
- Construct CREATE DATABASE command with Neo4j 5.26+ syntax
- Execute command via appropriate client connection
- Wait for completion (if
wait: true) - Import initial data (if specified)
- Update status with current state
Seed URI Database Creation:
- Discover target deployment and validate seed URI format
- Prepare cloud authentication (if
seedCredentialsspecified) - Construct CREATE DATABASE FROM URI command with CloudSeedProvider
- Execute command with seed configuration options
- Wait for restoration completion (if
wait: true) - Update status (Note: initial data import skipped - data comes from seed)
Version-Specific Behavior¶
Neo4j 5.26.x:
- Standard
CREATE DATABASEsyntax withTOPOLOGYclause - Seed URI support via CloudSeedProvider
- No point-in-time recovery for seed URIs
- No
DEFAULT LANGUAGE CYPHERclause:defaultCypherLanguage: "25"is rejected by validation, and"5"is accepted but omitted from the statement (every database runs Cypher 5) - Supports all topology and option features
- Compatible with both cluster and standalone deployments
Neo4j CalVer (2025.x and later):
- Enhanced
CREATE DATABASEwithDEFAULT LANGUAGE CYPHERsupport (defaultCypherLanguage"5"and"25"), applied on every create path - Point-in-time recovery for seed URIs (
restoreUntil) - Advanced seed configuration options and additional database options
- Enhanced topology management
- Same compatibility with cluster and standalone deployments
Reconciliation¶
The operator creates the database if it is missing, then observes it:
- If the database doesn't exist, it is created (with
topology,defaultCypherLanguage, seed andoptionsapplied at that moment) - If the database already exists, nothing about it is altered: later edits to
topology,options,defaultCypherLanguageor the seed fields are not applied, and the operator never starts or stops the database. UseALTER DATABASE …for those changes initialData.cypherStatementsrun once after creation (recorded instatus.dataImported)- Status (
state,servers,phase) is refreshed from the live database on every reconcile
Best Practices¶
General Best Practices¶
- Always use
ifNotExists: truein production to prevent reconciliation errors - Set appropriate topology based on your availability requirements
- Use
wait: truefor critical databases to ensure they're ready - Include IF NOT EXISTS in schema creation statements
- Test database creation in staging before production deployment
Seed URI Best Practices¶
- Prefer system-wide authentication (IAM roles, workload identity) over explicit credentials
- Use .backup format for better performance with large datasets compared to .dump format
- Don't combine
seedURIandinitialData- they conflict with each other - Use point-in-time recovery (
restoreUntil) when available for precise restoration - Test seed URI access from Neo4j pods before creating databases
- Monitor restoration progress - large backups may take significant time
- Use
seedConfig.configonly for seed-provider keys the provider documents (for exampleregionfor the S3SeedProvider); the operator passes them through unchanged
Troubleshooting¶
Database Creation Fails¶
Check operator logs:
Common Issues:
- Target Not Found:
clusterRefdoesn't match any cluster or standalone - Topology Validation: Insufficient servers for requested topology (cluster only)
- Name Conflicts: Database name already exists
- Authentication: Connection issues to Neo4j instance
- Seed URI Issues: Invalid format, inaccessible backup, credential problems
- Version Compatibility: Using 2025.x features with 5.26.x Neo4j
Cluster-Specific Issues:
- Server capacity exceeded (primaries + secondaries > cluster servers)
- Role constraint conflicts (e.g., requesting primaries from SECONDARY-only servers)
Standalone-Specific Issues:
- Topology specified for standalone deployment (will be ignored)
- Authentication configuration missing (
adminSecretnot configured)
Database Stuck in Pending¶
Verify target deployment:
# For cluster targets
kubectl get neo4jenterprisecluster <cluster-name>
kubectl describe neo4jenterprisecluster <cluster-name>
# For standalone targets
kubectl get neo4jenterprisestandalone <standalone-name>
kubectl describe neo4jenterprisestandalone <standalone-name>
# Check database status
kubectl describe neo4jdatabase <database-name>
kubectl get events --field-selector involvedObject.name=<database-name>
Common Causes:
- Target deployment not ready or in failed state
- Neo4j authentication issues
- Network connectivity problems
- Resource constraints (memory, CPU)
- Database name validation failures
Seed URI Troubleshooting¶
Authentication Issues:
# Check secret exists and has correct keys
kubectl get secret backup-credentials -o yaml
# Test access from a pod
kubectl run test-pod --rm -it --image=amazon/aws-cli \
-- aws s3 ls s3://my-bucket/backup.backup
URI Access Issues:
- Verify the backup file exists at the specified URI
- Check network connectivity from Neo4j pods to the URI
- Ensure firewall rules allow outbound access
- Test URI format:
scheme://host/path/file.backup
Performance Issues:
- Use
.backupformat instead of.dumpfor large datasets - Monitor pod resources during restoration
Validation Errors:
# Check for configuration conflicts
kubectl describe neo4jdatabase <database-name>
# Common validation errors:
# - seedURI and initialData cannot be used together
# - Database topology exceeds cluster capacity
# - Invalid URI scheme or format
# - Missing required credential keys in secret
Initial Data Not Imported¶
Troubleshooting Steps:
# Check database is online
kubectl exec <target-pod> -c neo4j -- \
cypher-shell -u neo4j -p <password> "SHOW DATABASES YIELD name, currentStatus WHERE name = '<db-name>'"
# Verify Cypher statements manually
kubectl exec <target-pod> -c neo4j -- \
cypher-shell -u neo4j -p <password> -d <db-name> "<test-statement>"
# Check operator logs for import errors
kubectl logs -n neo4j-operator-system -l control-plane=controller-manager --tail=-1 | grep -i "initial.*data"
Common Issues:
- Invalid Cypher syntax in statements
- Constraint/index name conflicts
- Database not fully online before import
- Insufficient privileges for data import
- Note: Initial data automatically skipped when using
seedURI - Standalone: Ensure
adminSecretproperly configures authentication
Seed URI Troubleshooting¶
Monitor Progress:
# Watch database creation events
kubectl get events --field-selector involvedObject.name=<database-name> --watch
# Check Neo4j logs for CloudSeedProvider activity
kubectl logs <target-pod> -c neo4j | grep -i "cloud.*seed\|restore"
# Verify seed URI accessibility
kubectl run test-uri --rm -it --image=curlimages/curl -- \
curl -I "<seed-uri>" # Test HTTP/HTTPS accessibility
Key Events:
DatabaseCreatedFromSeed: Successful seed URI restorationDataSeeded: Database seeding completedValidationWarning: Configuration or URI format warningsCreationFailed: Seed restoration failedSeedCredsMissing:seedCredentials.secretRefis not in the target'sspec.extraEnvFrom(and the target lacks theneo4j.com/auto-inherit-seed-credsannotation)SeedCredsAutoInherited: the operator added the Secret to the target'sspec.extraEnvFrom; waiting for the rolling restart
Authentication Debugging:
# Check secret exists and has correct format
kubectl get secret <seed-credentials-secret> -o yaml
# Test cloud credentials from pod
kubectl run aws-test --rm -it --image=amazon/aws-cli -- \
aws s3 ls <s3-bucket> # For S3 URIs
Performance Issues:
- Use
.backupformat instead of.dumpfor large datasets - Monitor pod resource usage during restoration