{"record":{"id":"a1103932f05f0a36","repo":"nginx/nginx","slug":"ngx-log-alert-a11039","errorCode":"NGX_LOG_ALERT","errorMessage":"sendfile() reported that \\\"%s\\\" was truncated at %O","messagePattern":"sendfile\\(\\) reported that \\\\\"(.+?)\\\\\" was truncated at %O","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/os/unix/ngx_freebsd_sendfile_chain.c","lineNumber":229,"sourceCode":"                }\n\n                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,\n                               \"sendfile() sent only %O bytes\", sent);\n\n            /*\n             * sendfile() in FreeBSD 3.x-4.x may return value >= 0\n             * on success, although only 0 is documented\n             */\n\n            } else if (rc >= 0 && sent == 0) {\n\n                /*\n                 * if rc is OK and sent equal to zero, then someone\n                 * has truncated the file, so the offset became beyond\n                 * the end of the file\n                 */\n\n                ngx_log_error(NGX_LOG_ALERT, c->log, 0,\n                         \"sendfile() reported that \\\"%s\\\" was truncated at %O\",\n                         file->file->name.data, file->file_pos);\n\n                return NGX_CHAIN_ERROR;\n            }\n\n            ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,\n                           \"sendfile: %d, @%O %O:%uz\",\n                           rc, file->file_pos, sent, file_size + header.size);\n\n        } else {\n            n = ngx_writev(c, &header);\n\n            if (n == NGX_ERROR) {\n                return NGX_CHAIN_ERROR;\n            }\n\n            sent = (n == NGX_AGAIN) ? 0 : n;","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/nginx/nginx/blob/3f6f7824d4e2eb1ac37dec76683d525ac0ff521c/src/os/unix/ngx_freebsd_sendfile_chain.c#L211-L247","documentation":"In ngx_freebsd_sendfile_chain(): FreeBSD sendfile() returned success (rc >= 0) but reported zero bytes sent, which means file_pos is at or beyond EOF - the file shrank after nginx opened it and cached its size. nginx logs this ALERT and returns NGX_CHAIN_ERROR, aborting the connection's output; the client connection is typically closed mid-response.","triggerScenarios":"A served static file is truncated after open: logrotate with copytruncate on files being downloaded, shell `> file` redirection or truncate -s 0 by deploy scripts, in-place rewrites by applications, or NFS re-exports changing size while open_file_cache holds stale metadata.","commonSituations":"Download/log files managed by logrotate copytruncate; deployment pipelines that truncate-and-rewrite instead of atomic rename; shared storage where another host rewrites the file; stale open_file_cache entries after upstream file changes.","solutions":["Replace files atomically: write new content to a temp name in the same directory and rename() it over the old path - never truncate a file nginx may be serving","If logrotate is the culprit, drop copytruncate and use create/rename plus postrotate `nginx -s reopen`","As a diagnostic or temporary workaround set `sendfile off;` so nginx read()s the file (still serves correct data, at a performance cost)","Flush open_file_cache (or lower open_file_cache_valid) if stale sizes keep reproducing the alert"],"exampleFix":"# before (logrotate)\n/var/www/files/*.bin {\n  copytruncate\n  weekly\n}\n# after\n/var/www/files/*.bin {\n  weekly\n  postrotate\n    [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`\n  endscript\n}","handlingStrategy":"validation","validationCode":"struct stat st;\nif (fstat(file->file->fd, &st) == 0 && file->file_pos > st.st_size) {\n    /* file shrank under us: re-open instead of sendfile()ing past EOF */\n}","typeGuard":"static ngx_int_t\nfile_not_truncated(ngx_file_t *f, off_t pos)\n{\n    struct stat  st;\n    return fstat(f->fd, &st) == 0 && pos <= st.st_size ? NGX_OK : NGX_ERROR;\n}","tryCatchPattern":"NGX_CHAIN_ERROR from the FreeBSD sendfile path aborts the connection's output chain: propagate it (close the connection, count the truncation), and fix the writer. Guard downstream by restat-ing size before sendfile and reopening when it shrank; ops-side, replace truncation with atomic rename.","preventionTips":["Publish files with write-temp-then-rename; never truncate-and-write in place","Replace logrotate copytruncate with rename plus `nginx -s reopen`","Keep open_file_cache_valid short on directories whose files change size often","Use `sendfile off` only as a diagnostic, not the cure"],"tags":["freebsd","sendfile","static-files","truncated-file","logrotate"],"backgroundTag":"file-truncated-while-serving","analyzedSha":"3f6f7824d4e2eb1ac37dec76683d525ac0ff521c","analyzedAt":"2026-08-22T03:09:46.447Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}