#577

BatchDelete panics in goroutine when namespace does not exist

Openyarkov-socureopened 10mo ago

Client Version: v6.14.1 Possibly Affected: v8+ (needs confirmation) Go Version: 1.24.6 API Affected: BatchDelete

When invoking BatchDelete with a key whose namespace does not exist on the Aerospike server, the client library panics inside a goroutine started internally, causing the entire application to crash.

This is due to a logic path where:

  • an error is added to records[i].Err in newBatchNodeList(...), but
  • no global err is returned (only record-level errors), and
  • a node is never assigned for that record (node == nil), yet
  • the executeAt() method later dereferences a nil node, causing a SIGSEGV.

The stacktrace:

1765558520830 panic: runtime error: invalid memory address or nil pointer dereference
1765558520830 [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1e65e79]
1765558520830 goroutine 127 [running]:
1765558520830 github.com/aerospike/aerospike-client-go/v6.(*baseCommand).executeAt(0xc0018e29a0, {0x6a28be0, 0xc0018e29a0}, 0xc0018dcd20, {0x0?, 0x5c6c358?, 0xa2ca160?}, 0x5cd2126?, 0x1b?)
1765558520830 .../vendor/github.com/aerospike/aerospike-client-go/v6/command.go:2601 +0x1eb9
1765558520830 github.com/aerospike/aerospike-client-go/v6.(*baseCommand).execute(0xc0018e29a0, {0x6a28be0, 0xc0018e29a0})
1765558520830 .../vendor/github.com/aerospike/aerospike-client-go/v6/command.go:2561 +0x65
1765558520830 github.com/aerospike/aerospike-client-go/v6.(*baseMultiCommand).execute(...)
1765558520830 .../vendor/github.com/aerospike/aerospike-client-go/v6/multi_command.go:415
1765558520830 github.com/aerospike/aerospike-client-go/v6.(*batchCommandDelete).Execute(0x4?)
1765558520830 .../vendor/github.com/aerospike/aerospike-client-go/v6/batch_command_delete.go:165 +0x1f
1765558520830 github.com/aerospike/aerospike-client-go/v6.(*werrGroup).execute.func1()
1765558520830 .../vendor/github.com/aerospike/aerospike-client-go/v6/werrgroup.go:62 +0xb1
1765558520830 created by github.com/aerospike/aerospike-client-go/v6.(*werrGroup).execute in goroutine 1
1765558520830 .../vendor/github.com/aerospike/aerospike-client-go/v6/werrgroup.go:55 +0x130
1765558520908 RequestId: b083c0a2-b94f-4816-8918-34b3f5b3f9f1 Error: Runtime exited with error: exit status 2 Runtime.ExitError
1765558520908 END RequestId: b083c0a2-b94f-4816-8918-34b3f5b3f9f1

Root Cause

In batch_node_list.go:51-53:

records[i].Err = chainErrors(err, records[i].Err)

The error is stored in the record, but not returned globally.

In client.go:946: if err != nil { return nil, err }

Only err != nil is checked — no validation that each record has a valid node.

This results in the downstream panic at command.go:2607:

for _, node := range cmd.nodes { ... conn, err := node.GetConnection(...) // node is nil here

Expected Behavior

If a key refers to a namespace that doesn’t exist, the client should:

  • Not panic
  • Return an appropriate error code per record, such as:
  • ResultCode.KEY_NOT_FOUND_ERROR, or
  • ResultCode.NAMESPACE_NOT_FOUND_ERROR (if defined)

Activity

2
mirzakaracic10mo ago

Thank you for reporting this @yarkov-socure. Will try to reproduce this locally for versions v6.14.1 and v8.5.0.

mirzakaracic10mo ago

@yarkov-socure Have confirmed the issue does exit in v8 branch. There is a PR with fix for v8 branch. Once the fix is merged will back port to v6 and v7 releases as well.