nginx/nginx · warning

NGX_LOG_ALERT

NGX_LOG_ALERT

Error message

<ngx_directio_on_n> \"%s\" failed

What it means

When a `directio <size>` threshold is configured and the file is at least that large, the module enables O_DIRECT on the file descriptor (ngx_directio_on) so the kernel cache is not polluted by the streaming transfer. If the filesystem rejects O_DIRECT, the call fails and this ALERT is logged; the transfer still proceeds on this code path.

Source

Thrown at src/http/modules/ngx_http_mp4_module.c:667

            }

            ngx_pfree(r->pool, mp4);

            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    log->action = "sending mp4 to client";

    if (clcf->directio <= of.size) {

        /*
         * DIRECTIO is set on transfer only
         * to allow kernel to cache "moov" atom
         */

        if (ngx_directio_on(of.fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                          ngx_directio_on_n " \"%s\" failed", path.data);
        }

        of.is_directio = 1;

        if (mp4) {
            mp4->file.directio = 1;
        }
    }

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.last_modified_time = of.mtime;

    if (ngx_http_set_etag(r) != NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (ngx_http_set_content_type(r) != NGX_OK) {

View on GitHub (pinned to 3f6f7824d4)

Solutions

  1. Set `directio off;` (the default) in the mp4 location unless benchmarking on the real filesystem shows a win.
  2. Or move the media to a filesystem with O_DIRECT support such as ext4 or xfs.
  3. If you keep directio, accept the ALERT per file but confirm responses still stream correctly; silence noise by disabling the directive.

Example fix

# before
location ~ \.mp4$ {
    mp4;
    directio 4m;      # ALERT: files sit on tmpfs without O_DIRECT
}

# after
location ~ \.mp4$ {
    mp4;
    directio off;     # default; kernel caching of moov stays enabled
}
Defensive patterns

Strategy: validation

Validate before calling

# probe O_DIRECT support on the serving filesystem before enabling directio
python3 - <<'PY'
import os
try:
    fd = os.open('/data/videos/a.mp4', os.O_RDONLY | os.O_DIRECT)
    print('O_DIRECT supported'); os.close(fd)
except OSError as e:
    print('O_DIRECT failed:', e)   # errno 22/25 -> keep directio off
PY

Prevention

When it happens

Trigger: Serving an mp4 at or above the directio threshold from a filesystem without O_DIRECT support: tmpfs (/dev/shm), many FUSE mounts, some NFS configurations, certain container overlay setups.

Common situations: `directio 4m;` copied from static-file tuning guides while the videos actually live on tmpfs or an exotic mount; moving data dirs to /dev/shm for speed without revisiting directio settings.

Related errors


AI-assisted analysis of nginx/nginx@3f6f7824d4 (2026-08-22). Data as JSON: /api/errors/25b5e090a0a61fc6. Report an issue: GitHub.