Known limitations
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
This page outlines the technical limitations of Aerospike’s UDF system, including module filename allowlist rules, default and hardened sandbox restrictions on Lua libraries, stack buffer limits, and functional boundaries regarding return types, record bin limits, and transaction locking.
Lua Limitations
-
Please see Getting Started section for Lua modifications.
-
A large number of function parameters (~ >50) causes instability in the Lua Runtime Engine.
-
The stack buffer limit in Lua is 65500. For example, attempting to pass 20000 4-byte arguments to a Lua function will result in a stack overflow error.
-
Integers are represented as 64-bit LONGLONG datatypes.
Module filename allowlist
Available in Aerospike Database 8.1.2.2, 8.0.0.17, 7.2.0.19, 7.1.0.25.
UDF module names must conform to a fixed allowlist:
- Use only ASCII letters, digits, and the characters
.,_,-, and$([A-Za-z0-9._$-]). - Be non-empty.
- Not begin with
.. - Not contain the substring
...
Non-conforming names are rejected with error=invalid_filename. See UDF security and sandbox hardening for cleanup guidance for entries already registered with names that fail these rules.
Restrictions on Lua libraries (default mode)
When mod-lua.allow-unsafe-lua is true (the default), the following restrictions on Lua libraries are enforced because of potential security vulnerabilities:
- Calling functions from the Lua
iolibrary is not allowed. - The Lua
debuglibrary is not available. os.exit()is not available.- The only functions from the Lua
oslibrary that can be called are as follows:os.clock()os.date()os.difftime()os.time()
Additional restrictions under hardened mode
When mod-lua.allow-unsafe-lua is set to false, hardened mode replaces the default sandbox with stricter restrictions:
- The
os,io,debug,dofile,loadfile,load, andloadstringLua globals are removed entirely. The fouros.*functions allowed in default mode are not available in hardened mode. package.searchpath,package.loadlib, andpackage.cpathare removed.- Native
.soUDF modules cannot be registered. - Precompiled Lua bytecode UDFs are rejected at registration with a compile error; Lua chunks are loaded in text-only mode.
- The
.luaextension is checked case-sensitively at registration. Mixed-case extensions such as.LUAor.Luaare rejected witherror=unsafe_lua_disabled.
See UDF security and sandbox hardening for the full list and a migration checklist before opting in.
Functional limitations
- Stream UDF functions which implement map, aggregate, or reduce and record UDF functions must return one of the types supported by the database: integer, string, bytes, list, and map. It is NOT possible to return a record type.
- A Lua table cannot be used to return key-value pairs. Instead, the Aerospike defined map type should be used.
- In general, UDFs cannot access or write records with more than 512 bins. Read-only UDFs that access only metadata, not bins, are not subject to this bin limit.
- UDFs within one record scope cannot access another record.
- Stream UDF functions are read-only functions. Only record UDF functions can be read/write.
- UDF de-registration does not follow the “require” dependency tree. As a result, when deleting “parent.lua”, which is required by “child.lua”, user must explicitly delete “child.lua” as well.
- A record UDF command inside a transaction will lock the record (blocking others from writing to it with an
AS_ERR_MRT_BLOCKEDerror code 120) regardless of whether it performs read or write operations.
Cache Limitations
- 10 Lua states are initially cached on each node for every registered module. Additional states are cached as needed at runtime up to a maximum of 128 per module. If 128 or more invocations of the same UDF are running simultaneously on the node, performance will be impacted by any additional invocations of the UDF, as Lua states will be created to service them.
- Cache invalidation happens only when the top-level module is updated. Any update to dependency modules (aka the “required” modules are updated) does not invoke a cache invalidation. Work around is to manually invalidate caches on all nodes. see Managing UDFs