SagerNet / SagerNet/sing-box

OpenWrt/musl ARM64 (CGO enabled) builds never accept TCP connections — 1.13.19, both official .ipk and generic -musl release affected

Open
#4,430 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
38.2k
Forks
4.6k
Avg merge
19d 15h
Merged PRs (30d)
1

Description

Operating system

OpenWrt (aarch64, musl)

System version
DISTRIB_ID='OpenWrt'
DISTRIB_RELEASE='21.02-SNAPSHOT'
DISTRIB_REVISION='r15812+900-46b6ee7ffc'
DISTRIB_TARGET='mediatek/mt7981'
DISTRIB_ARCH='aarch64_cortex-a53'
Linux 5.4.211 aarch64
musl libc 1.1.24 (ld-musl-aarch64.so.1)
Device: GL.iNet GL-MT2500 (MediaTek MT7981B, Cortex-A53)
Installation type

Original sing-box Command Line (manual binary, run directly — not opkg-installed as a service)

Version
sing-box version 1.13.19

Environment: go1.25.12 linux/arm64
Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_naive_outbound,badlinkname,tfogo_checklinkname0,with_musl
CGO: enabled

Reproduced identically on two independently-built binaries:

  • sing-box-1.13.19-linux-arm64-musl.tar.gz (generic musl release asset)
  • sing-box_1.13.19_openwrt_aarch64_cortex-a53.ipk (official OpenWrt package for this exact device/arch)
Description

Summary

On this musl/aarch64 OpenWrt device, any 1.13.19 build with CGO: enabled (i.e. every ARM64 musl-linked build sing-box currently ships) starts and reports a successful listen, but never accepts a single TCP connection — not even from a process on the same machine connecting to the bound address. The listening socket is real and correctly bound (confirmed via netstat), but accept() is never observed to fire: no "inbound connection from ..." log line ever appears, even with "log": {"level": "trace"}.

By contrast, sing-box 1.12.17 (CGO: disabled, pure static Go binary) works correctly on the exact same device, exact same config, exact same network path.

Reproduction

Config (config.json):

{
  "log": { "level": "trace" },
  "inbounds": [
    {
      "type": "mixed",
      "listen": "192.168.8.1",
      "listen_port": 1087
    }
  ],
  "outbounds": [
    {
      "type": "vless",
      "server": "<remote server IP>",
      "server_port": 443,
      "uuid": "...",
      "flow": "xtls-rprx-vision",
      "tls": {
        "enabled": true,
        "server_name": "...",
        "utls": { "enabled": true, "fingerprint": "chrome" },
        "reality": { "enabled": true, "public_key": "...", "short_id": "..." }
      }
    }
  ]
}
./sing-box run -c config.json

Log output — this is the entire log, no further lines ever appear regardless of how many connection attempts are made:

INFO[0000] network: updated default interface eth0, index 2
INFO[0000] inbound/mixed[0]: tcp server started at 192.168.8.1:1087
INFO[0000] sing-box started (0.01s)

Confirming the socket is genuinely bound and listening:

$ netstat -tlnp | grep 1087
tcp   0   0   192.168.8.1:1087   0.0.0.0:*   LISTEN   <pid>/sing-box

Attempting to connect (from a process on the same device, so no external firewall/NAT is involved):

$ curl --socks5 192.168.8.1:1087 http://example.com
curl: (28) Connection timed out after 8000 milliseconds

$ nc -zv 192.168.8.1 1087
(hangs, no SYN-ACK, eventually times out)

Also reproduced binding to pure loopback (127.0.0.1, different port, to rule out anything specific to the LAN-zone address) — identical result: listens, never accepts.

What works instead

Same device, same config (adjusted only for the binary path), 1.12.17:

sing-box version 1.12.17
Environment: go1.25.6 linux/arm64
Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale
CGO: disabled
INFO[0000] inbound/mixed[0]: tcp server started at 192.168.8.1:1087
INFO[0000] sing-box started (0.11s)
INFO[0011] [...] inbound/mixed[0]: inbound connection from 192.168.8.1:57964

Connects immediately and proxies traffic correctly.

Notes / suspected cause

  • I don't have a fix, just isolation. The only difference between the working and broken builds (that I can find in the release matrix) is CGO: enabled + musl dynamic linking vs. CGO: disabled + fully static.
  • The device's musl runtime is quite old (1.1.24, from OpenWrt 21.02); if the release toolchain builds -musl assets against a materially newer musl (e.g. via a modern musl-cross-make toolchain), an ABI/behavioral mismatch in accept()/epoll-related paths seems like a plausible culprit, but I haven't verified this against sing-box's actual build toolchain — flagging as a hypothesis, not a diagnosis.
  • The plain (non-suffixed) sing-box-1.13.19-linux-arm64.tar.gz build can't be used as a control here — it appears to be glibc-dynamically-linked (likely due to the bundled libcronet.so for the NaiveProxy feature added in 1.13.0) and fails to execute at all on this musl-only system (no such file or directory at exec time, despite the file existing — classic missing-interpreter symptom), so it's not usable to test a "CGO disabled + not musl-linked" ARM64 build in isolation on this platform.
Logs

Already included inline above (full logs, nothing trimmed — the log output really is that short).

Supporter
Integrity requirements
  • I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
  • I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
  • I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
  • I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

First reproduce the failure on the documented OpenWrt aarch64/musl environment using the minimal mixed inbound configuration and compare it with sing-box 1.12.17. Trace the TCP accept and epoll-related path in the 1.13.19 CGO-enabled build, then verify that connections are accepted on both the LAN address and 127.0.0.1 while preserving the working static-build behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, linux
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.