{"record":{"id":"993f809f636004af","repo":"aeron-io/aeron","slug":"einval-initialcapacity-outside-range-0-max-capacity","errorCode":"EINVAL","errorMessage":"initialCapacity outside range 0 - ${max}${capacity}","messagePattern":"initialCapacity outside range 0 - (.+?)(.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"aeron-client/src/main/cpp_wrapper/BufferBuilder.h","lineNumber":39,"sourceCode":"#include \"Aeron.h\"\n\nnamespace aeron\n{\n\nstatic constexpr std::uint32_t BUFFER_BUILDER_MAX_CAPACITY = std::numeric_limits<std::int32_t>::max() - 8;\nstatic constexpr std::uint32_t BUFFER_BUILDER_INIT_MIN_CAPACITY = 4096;\n\nclass BufferBuilder\n{\npublic:\n    using this_t = BufferBuilder;\n\n    explicit BufferBuilder(std::uint32_t initialCapacity = 0) :\n        m_capacity(initialCapacity),\n        m_buffer(new std::uint8_t[m_capacity])\n    {\n        if (BUFFER_BUILDER_MAX_CAPACITY < m_capacity)\n        {\n            throw IllegalArgumentException(\n                \"initialCapacity outside range 0 - \" + std::to_string(BUFFER_BUILDER_MAX_CAPACITY) +\n                \": capacity=\" + std::to_string(m_capacity), SOURCEINFO, EINVAL);\n        }\n    }\n\n    BufferBuilder(BufferBuilder &&builder) noexcept:\n        m_capacity(builder.m_capacity),\n        m_limit(builder.m_limit),\n        m_nextTermOffset(builder.m_nextTermOffset),\n        m_buffer(std::move(builder.m_buffer))\n    {\n    }\n\n    std::uint8_t *buffer() const\n    {\n        return &m_buffer[0];\n    }","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-client/src/main/cpp_wrapper/BufferBuilder.h#L21-L57","documentation":"BufferBuilder validates that its initial allocation does not exceed BUFFER_BUILDER_MAX_CAPACITY. Passing an initialCapacity above that compile-time maximum would allocate a buffer the builder can never grow within, so the constructor throws IllegalArgumentException with EINVAL.","triggerScenarios":"Constructing BufferBuilder with an explicit initialCapacity greater than BUFFER_BUILDER_MAX_CAPACITY (e.g. BufferBuilder builder(2u << 30)).","commonSituations":"Tuning initial capacity for large fragments and overshooting the maximum; porting code that assumed a 64-bit capacity constant; copying a capacity value from a differently-configured build.","solutions":["Pass an initialCapacity <= BUFFER_BUILDER_MAX_CAPACITY, or use the default 0","Check the requested capacity against BUFFER_BUILDER_MAX_CAPACITY before constructing","Clamp or scale down large capacity requests at configuration load time"],"exampleFix":"// before\nconcurrent::atomic::BufferBuilder builder(3u * 1024 * 1024 * 1024u); // exceeds max\n// after\nconstexpr std::uint32_t cap = std::min(requested, BUFFER_BUILDER_MAX_CAPACITY);\nconcurrent::atomic::BufferBuilder builder(cap);","handlingStrategy":"validation","validationCode":"if (initialCapacity > BUFFER_BUILDER_MAX_CAPACITY) {\n    initialCapacity = BUFFER_BUILDER_MAX_CAPACITY; // or reject the config\n}","typeGuard":null,"tryCatchPattern":"try {\n    concurrent::atomic::BufferBuilder builder(initialCapacity);\n} catch (const aeron::util::IllegalArgumentException& e) {\n    // clamp and retry\n}","preventionTips":["Clamp configured capacities against BUFFER_BUILDER_MAX_CAPACITY at load time","Prefer the default constructor (initialCapacity = 0) unless profiling shows a need","Note the constant is 32-bit: never pass values derived from 64-bit size math"],"tags":["aeron","cpp","buffer","capacity"],"backgroundTag":"value-out-of-range","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}