Nim version 2.2.14 released
28 October 2026 The Nim Team
The Nim Team is happy to announce version 2.2.14, the seventh patch release for our stable release, Nim 2.2.
It comes seven weeks after the 2.2.12 release and it contains 142 commits, bringing bugfixes and improvements.
If you’re still on Nim 1.6, take a look at the version 2.0 release article to see all the features you’re missing. If you’ve been using Nim 2.0, the version 2.2 release article shows the improvements available in Nim 2.2.
Installing Nim 2.2.14
Check out if the package manager of your OS already ships version 2.2.14 or install it as described here.
If you have installed a previous version of Nim using choosenim,
getting Nim 2.2.14 is as easy as:
$ choosenim update self
$ choosenim update stable
NOTE: We recommend that you install and use the latest version of choosenim, v0.8.16, available in our choosenim repo.
Alternatively, you can download Nim 2.2.14 from our nightlies builds.
Security fixes
This release hardens several standard library modules against malicious input:
httpclient: on a redirect that leaves the origin (scheme, host, port) of the requested URL, theAuthorization,CookieandHostheaders are now dropped, so a server can no longer redirect the client to a host it controls and read its credentials. (STD-001)asynchttpserver: request bodies are now always read completely. Chunked bodies of methods other than POST, chunk extensions and trailer fields could previously be parsed as the next request on the connection, which allowed request smuggling behind a reverse proxy. (STD-002)asynchttpserver: requests with ambiguous body framing (bothContent-LengthandTransfer-Encoding, repeated or malformedContent-Length, unknown transfer codings, whitespace before the colon) are now rejected following RFC 9112, section 6.3. (STD-003)net,asyncnet: when a TLS client connects to an IP address, the address is now checked against the certificate’s IP SANs. Previously any certificate signed by a trusted CA was accepted. (STD-004)cmdline:parseCmdLine(and thusparseopt.initOptParser(string)) no longer loops forever and exhausts memory on control characters. (STD-005)httpclient: CR, LF and NUL in the request target, the Host header and header fields now raiseValueErrorinstead of allowing header and request injection. (STD-006)xmlparser,htmlparser: the nesting depth is now limited (xmlMaxDepth, 256, andhtmlMaxDepth, 512, both{.intdefine.}s), so deeply nested input can no longer exhaust the stack. (STD-007)xmltree: the output of$is no longer quadratic in the nesting depth; indentation stops growing at 80 columns. (STD-008)httpclient: chunk sizes that overflow anintnow raiseProtocolErrorinstead of wrapping around and misframing the body. (STD-009)
Additionally, asyncnet now verifies the TLS hostname
(#26455).
Bugfixes
- Fixed “
[GCASSERT] incRef: interiorPtrTraceback/SIGSEGVwith closure iterator iterating over tuples inrefc” (#26158) - Fixed “cyclic
reftype with lifetime extend beyond nested function calls setting it creates UB in ORC” (#26172) - Fixed “nim js: explicit {.closure.} on a lambda with parameters crashes codegen” (#26176)
- Fixed “
wrapWords(splitLongWords = true)drops the separator before a word it has to split” (#26183) - Fixed “Closure iterator local released at
yieldinstead of scope exit” (#26041) - Fixed “Nim 2.2.12 compiler SIGSEGV with –exceptions:setjmp in try/except/finally” (#26189)
- Fixed “TSlice returned by template as an expr does not work in range[]” (#560)
- Fixed “
strutils.rsplitmishandles overlapping separators” (#24949) - Fixed “Wrong sizeof computed on linux for certain types (abi mismatch)” (#26220)
- Fixed “vm: cast to distinct pointer broken” (#26213)
- Fixed “
sizeofmiscomputed in object with void fields” (#26225) - Fixed “Provide an alternative format for error/warning messages; eg: file:line:col instead of file(line, col)” (#690)
- Fixed “AST: nkIfExpr missing typ” (#26218)
- Fixed “memory leak with nested Exceptions via function” (#25037)
- Fixed “Closure environment is moved (
=wasMoved) while still live: SIGSEGV on a later read” (#26247) - Fixed “Duplicate/redundant
nimZeroMem()in--mm:refc” (#23383) - Fixed “Document isMainModule and appType for libraries” (#17496)
- Fixed “Wrong sizeof computation in sizeof test” (#26255)
- Fixed “nimsuggest, nim check: nimbus-eth1: SIGSEGV: Illegal storage access. (Attempt to read from nil?)” (#26244)
- Fixed “
type T[P]=proc{.f.}innim checktriggersunhandled exception: field 'sym' is not accessible for type 'TNode' using 'kind = nkIdent'” (#26260) - Fixed “std/uri , removeDotSegments: i advancement incorrectly conditional on stack being non-empty” (#26259)
- Fixed “
whenexpression not considered as such in type section” (#26272) - Fixed “74f4042f8 (#24867) causes significant compile-time regression” (#26349)
- Fixed “TSAN-detected data race on ARM64 Linux with
createThread/joinThreadwith ORC and refc” (#26354) - Fixed “Object constructor with an array field reading the destination gives a wrong value” (#26329)
- Fixed “importc distinct pointer shares C typedef with pointer in proc types” (#26312)
- Fixed “–debugger:native: unreachable assertion with default static generic parameters” (#26336)
- Fixed “Generic instantiation treats different importc aliases of pointer as identical” (#26311)
- Fixed “Closure iterator with try/except and yield SIGSEGVs then hangs” (#26337)
- Fixed “VM memory leak during compilation in iterating over
seqelements” (#26273) - Fixed “nimsuggest:
defnot working properly with./[module1, module2]syntax” (#26307) - Fixed “Closure iterator: yield inside an expression pragma block crashes the compiler” (#26335)
- Fixed “Closure iterator: case on an if expression skips all branches” (#26324)
- Fixed “
getTypeImplof genericref objectinstance has uninstantiated field types” (#26374) - Fixed “Assigning to moved-from nested case object frees the moved seq” (#26369)
- Fixed “marshal.load into a reset case object writes through a freed string” (#26370)
- Fixed “
strutils.formatFloatuses a 2500 character buffer for sprintf output” (#26330) - Fixed “arc/orc:
addof an empty string to a literal-backed string leaves no NUL terminator” (#26411) - Fixed “
vccplatform()missingcpuArm64case — Windows ARM64 builds fail with LNK1112” (#26434) - Fixed “Windows/ARM64 with MSVC: dragonbox uses the x64-only _umul128 intrinsic (LNK2019)” (#26250)
- Fixed “Closure iterator SIGSEGV: nested try with yield inside except” (#26291)
- Fixed “
{.push checks: off.}around an import disables checks in the imported module” (#26431) - Fixed “vccexe: –platform:arm64 and –platform:arm crash with “Invalid enum value” — the stock tool rejects the flags extccomp emits for ARM targets” (#26453)
- Fixed “Cannot resolve pragmas when new type is defined from
typeofexpression” (#25140) - Fixed “
hasCustomPragmafails on field inherited from generic object” (#26372) - Fixed “
hasCustomPragmaignores fields declared underwhen” (#26373) - Fixed “
hasCustomPragmahits VM iteration limit fortypeofalias of generic instance” (#26400) - Fixed “devel Regression:
getTypeImplreturns a symbol for atypeofalias of a generic instance” (#26412) - Fixed “ARC/ORC: Option value freed while variable in outer scope aliases it” (#26461)
- Fixed “finally sees a variable assigned from a call that raised in –mm:orc” (#26333)
- Fixed “False
'cmd' should be: 'Cmd'styleCheck error for a field type taken from getTypeImpl” (#26464) - Fixed “
unicode.stripraises IndexDefect on a string ending in a truncated UTF-8 sequence” (#26415) - Fixed “unicode.splitWhitespace() and strutils.splitWhitespace() have different results for ASCII string” (#23619)
- Fixed “Issue with insertSep function in strutils” (#24788)
- Fixed “xmltree does not escape newlines but prevents them from being escaped” (#24062)
- Fixed “Compiler crashes with IndexDefect on
O[]as a parameter type” (#26477) - Fixed “getCursorPos() from std/terminal is off by one on POSIX” (#26301)
- Fixed “
parseXmlunexpectedly createsxnTextnodes after encountering an xml comment” (#25462) - Fixed “asyncnet: TLS hostname is never verified on any platform — AsyncSocket and AsyncHttpClient accept any CA-valid certificate for any hostname” (#26455)
- Fixed “
times.parseraises RangeDefect instead of TimeParseError for minute 60-99 or second 61-99” (#26408) - Fixed “signalHandler hangs with –gc:boehm when the signal comes from inside Boehm (GC_disable deadlocks)” (#26513)
- Fixed “Method call on a
var-param call passes the argument by value” (#26521) - Fixed “-d:useMalloc doesn’t check malloc/calloc/realloc for nil outside Zephyr” (#26331)
- Fixed “
seq[var T].mitems()uses incorrect element stride for variant case-object T with 2+ elements, causing writes to the wrong element’s memory” (#26058) - Fixed “Pragma alias expands to
p()instead ofpafter its first use” (#26473) - Fixed “Bad error message for
forbidsviolation” (#25978) - Fixed “refc:
=dupof a seq whose element type has a hook returns an empty seq” (#26540) - Fixed “Regression from 2.2.x to
version-2-4/develindoAssert [0].items.typeof is int” (#26547) - Fixed “[Regression 2.2.12 –> 2.2.13/2.4/devel] refc: GC marker reads uninitialized
Dequeslots of case objects” (#26539) - Fixed “refc: resetting a case object zeroes GC-free arrays element by element” (#26552)
The complete list of changes is available here.