redis/redis · critical

Out of memory

Error message

Out of memory

What it means

Emitted by fpconv_strtod() then abort() when malloc() fails for an unusually large numeric token. This path only triggers for numbers longer than FPCONV_G_FMT_BUFSIZE that also use a non-dot locale decimal.

Source

Thrown at deps/lua/src/fpconv.c:129

    double value;

    /* System strtod() is fine when decimal point is '.' */
    if (locale_decimal_point == '.')
        return strtod(nptr, endptr);

    buflen = strtod_buffer_size(nptr);
    if (!buflen) {
        /* No valid characters found, standard strtod() return */
        *endptr = (char *)nptr;
        return 0;
    }

    /* Duplicate number into buffer */
    if (buflen >= FPCONV_G_FMT_BUFSIZE) {
        /* Handle unusually large numbers */
        buf = malloc(buflen + 1);
        if (!buf) {
            fprintf(stderr, "Out of memory");
            abort();
        }
    } else {
        /* This is the common case.. */
        buf = localbuf;
    }
    memcpy(buf, nptr, buflen);
    buf[buflen] = 0;

    /* Update decimal point character if found */
    dp = strchr(buf, '.');
    if (dp)
        *dp = locale_decimal_point;

    value = strtod(buf, &endbuf);
    *endptr = (char *)&nptr[endbuf - buf];
    if (buflen >= FPCONV_G_FMT_BUFSIZE)
        free(buf);

View on GitHub (pinned to 4f20cb4893)

Solutions

  1. Alleviate memory pressure (raise vm.overcommit / add RAM / reduce dataset).
  2. Validate/reject absurdly long numeric tokens before passing JSON to cjson.
  3. Run under LC_NUMERIC=C so the malloc path is never taken.
  4. Cap the strtod_buffer_size and reject inputs above the cap before malloc.

Example fix

// before
if (buflen >= FPCONV_G_FMT_BUFSIZE) {
    buf = malloc(buflen + 1);
    if (!buf) { fprintf(stderr, "Out of memory"); abort(); }
}
// after
if (buflen >= FPCONV_G_FMT_BUFSIZE) {
    buf = malloc(buflen + 1);
    if (!buf) { *endptr = (char *)nptr; return 0; }  /* degrade, do not abort */
}
Defensive patterns

Strategy: validation

Validate before calling

/* Reject absurdly long numeric tokens before handing JSON to cjson. */
size_t n = strspn(json, "0123456789eE.+-aAbBcCdDfFpPxX");
if (n > 64) return JSON_PARSE_ERROR;   /* not a sane number */

Prevention

When it happens

Trigger: At deps/lua/src/fpconv.c:127-130, when buflen >= FPCONV_G_FMT_BUFSIZE the code mallocs a buffer; if malloc returns NULL it prints 'Out of memory' and abort(). Requires both a non-'.' locale and an input number token spanning more than the stack buffer.

Common situations: Parsing JSON with pathologically long numeric literals under memory pressure while a comma-decimal locale is active; cjson fed untrusted huge-number input during OOM.

Related errors


AI-assisted analysis of redis/redis@4f20cb4893 (2026-08-10). Data as JSON: /api/errors/09b42b41df6c1262. Report an issue: GitHub.