#2046·tengine

Build failed with ngx_http_xquic_module due to undefined reference to ngx_xquic_record_recv_pkts

Author: xiaozhimengmengdaCreated Jun 17, 2026Updated Aug 1, 2026

Ⅰ. Issue Description

When building Tengine 3.1.0 with ngx_http_xquic_module enabled, the final link step fails with an undefined reference to ngx_xquic_record_recv_pkts.

The function is defined in modules/ngx_http_xquic_module/ngx_xquic_recv.c as an inline function:

c
inline void
ngx_xquic_record_recv_pkts(ngx_int_t record_interval, char *mode, uint64_t *total_recv_count,
    uint64_t *last_recv_count, ngx_msec_t *last_record_time)
{
    ...
}

But during the final link step, the symbol is not resolved:

/usr/bin/ld: objs/addon/ngx_http_xquic_module/ngx_xquic_recv.o: in function `ngx_xquic_dispatcher_process_packet':
ngx_xquic_recv.c:(.text+0xc6e): undefined reference to `ngx_xquic_record_recv_pkts'
collect2: error: ld returned 1 exit status
make[1]: *** [objs/Makefile:352: objs/nginx] Error 1
make[1]: Leaving directory '/data/install_tengine/tengine-3.1.0'
make: *** [Makefile:10: build] Error 2

Changing the function from inline void to static inline void fixes the build in my environment.

c
static inline void
ngx_xquic_record_recv_pkts(ngx_int_t record_interval, char *mode, uint64_t *total_recv_count,
    uint64_t *last_recv_count, ngx_msec_t *last_record_time)
{
    ...
}

This seems to be related to C inline linkage semantics under newer GCC versions.

Ⅱ. Describe what happened

I built Tengine 3.1.0 with ngx_http_xquic_module and XQUIC enabled.

The XQUIC library was built and linked with Tengine. The previous XQUIC symbols such as xqc_h3_request_recv_body, xqc_h3_request_send_headers, and xqc_engine_finish_send were resolved after adding -lxquic.

However, the final nginx link step still failed because ngx_xquic_record_recv_pkts could not be resolved.

Relevant error:

/usr/bin/ld: objs/addon/ngx_http_xquic_module/ngx_xquic_recv.o: in function `ngx_xquic_dispatcher_process_packet':
ngx_xquic_recv.c:(.text+0xc6e): undefined reference to `ngx_xquic_record_recv_pkts'
collect2: error: ld returned 1 exit status
make[1]: *** [objs/Makefile:352: objs/nginx] Error 1
make[1]: Leaving directory '/data/install_tengine/tengine-3.1.0'
make: *** [Makefile:10: build] Error 2

After changing ngx_xquic_record_recv_pkts from inline void to static inline void, the undefined reference issue was resolved.

Ⅲ. Describe what you expected to happen

Tengine should build successfully with ngx_http_xquic_module enabled.

The helper function ngx_xquic_record_recv_pkts should not cause an undefined reference during the final link step.

If the function is only used inside ngx_xquic_recv.c, it may be better to define it as static inline instead of plain inline.

Ⅳ. How to reproduce it (as minimally and precisely as possible)

  1. Build and install XQUIC 1.9.3 with BabaSSL / TongSuo 8.3.3.

  2. Build Tengine 3.1.0 with ngx_http_xquic_module enabled:

bash
./configure \
  --prefix=/usr/local/nginx \
  --user=nginx \
  --group=nginx \
  --with-http_v2_module \
  --with-http_ssl_module \
  --with-stream \
  --with-stream_ssl_preread_module \
  --with-stream_ssl_module \
  --with-stream_realip_module \
  --with-http_realip_module \
  --with-threads \
  --with-http_slice_module \
  --with-openssl="../Tongsuo-8.3.3" \
  --with-openssl-opt="-fPIC no-shared no-threads" \
  --with-pcre="../pcre2-10.37" \
  --with-pcre-jit \
  --with-jemalloc \
  --with-cc-opt="-fPIC -I/usr/local/include" \
  --with-ld-opt="-L/usr/local/lib -Wl,-rpath,/usr/local/lib -lxquic -ldl -lpthread -lm" \
  --add-module=modules/ngx_http_xquic_module
  1. Run make:
bash
make -j1 V=1

Then the final link step fails with:

undefined reference to `ngx_xquic_record_recv_pkts'

Workaround:

bash
perl -0pi -e 's/\ninline void\nngx_xquic_record_recv_pkts/\nstatic inline void\nngx_xquic_record_recv_pkts/' \
  modules/ngx_http_xquic_module/ngx_xquic_recv.c

After applying this workaround and rebuilding, the undefined reference is resolved.

Ⅴ. Anything else we need to know?

This issue appears to be caused by C inline linkage semantics.

In modules/ngx_http_xquic_module/ngx_xquic_recv.c, ngx_xquic_record_recv_pkts is currently defined as:

c
inline void
ngx_xquic_record_recv_pkts(...)

Changing it to:

c
static inline void
ngx_xquic_record_recv_pkts(...)

fixes the build in my environment.

Ⅵ. Environment:

  • Tengine version (use sbin/nginx -V): Tengine 3.1.0 source build

  • OS (e.g. from /etc/os-release): Ubuntu 24.04

  • Kernel (e.g. uname -a): please fill in your actual uname -a output

  • Others:

    • GCC: 13.x
    • XQUIC: 1.9.3
    • SSL backend: BabaSSL / TongSuo 8.3.3
    • PCRE2: 10.37
    • Jemalloc: 5.3.0