Skip to content

fix(naive): stop sending unsupported alpn/insecure to sing-box naive outbound#46

Merged
dododook merged 1 commit into
dododook:mainfrom
Sway-Chan:fix/naive-alpn
Jun 8, 2026
Merged

fix(naive): stop sending unsupported alpn/insecure to sing-box naive outbound#46
dododook merged 1 commit into
dododook:mainfrom
Sway-Chan:fix/naive-alpn

Conversation

@Sway-Chan

Copy link
Copy Markdown
Collaborator

Problem

FlowZ builds the naive outbound's TLS block with alpn and insecure:

outbound.tls = {
  enabled: true,
  server_name: server.tlsSettings?.serverName || server.address,
  insecure: server.tlsSettings?.allowInsecure || false,
  alpn: server.tlsSettings?.alpn || undefined,
};

But sing-box's naive outbound uses Cronet, which manages its own TLS, and only server_name / certificate / certificate_path / ech are supported. Passing alpn, or insecure: true, makes sing-box hard-fail at startup:

FATAL: initialize outbound: alpn is not supported on naive outbound
FATAL: initialize outbound: insecure is not supported on naive outbound

So a naive node that carries an ALPN (e.g. from an imported subscription) or has "allow insecure" enabled causes the core to refuse to start. Reproduced with the bundled sing-box check (1.13.3): alpn:["h3"]alpn is not supported on naive outbound; insecure:trueinsecure is not supported on naive outbound; server_name-only → accepted.

Fix

Emit only server_name for the naive outbound TLS. The alpn / allowInsecure the user may have set on the node are ignored, since sing-box's naive cannot honour them anyway (and the docs explicitly advise against self-signed certs for naive).

References

  • sing-box docs — Naive outbound TLS supports only server_name / certificate / certificate_path / ech: https://sing-box.sagernet.org/configuration/outbound/naive/
  • sing-box source — protocol/naive/outbound.go (v1.13.x), ~L47: if len(options.TLS.ALPN) > 0 { return nil, E.New("alpn is not supported on naive outbound") } (plus the analogous insecure check).

Testing

tsc -p tsconfig.main.json, eslint, prettier clean; the post-fix naive outbound (server_name only) validated by the bundled sing-box check.

🤖 Generated with Claude Code

…outbound

FlowZ built the naive outbound TLS with `alpn` and `insecure`, but
sing-box's naive outbound (Cronet manages its own TLS) supports only
server_name/certificate/certificate_path/ech and hard-fails at startup
if either is set:

  FATAL: initialize outbound: alpn is not supported on naive outbound
  FATAL: initialize outbound: insecure is not supported on naive outbound

So a naive node with a custom ALPN, or with "allow insecure" enabled,
made sing-box refuse to start. Only emit server_name for naive (the
unsupported alpn / allowInsecure on the node are ignored, as sing-box
cannot honour them anyway).

Refs:
- https://sing-box.sagernet.org/configuration/outbound/naive/
  (naive TLS supports only server_name / certificate / certificate_path / ech)
- SagerNet/sing-box protocol/naive/outbound.go (v1.13.x) ~L47
  `E.New("alpn is not supported on naive outbound")` (+ the insecure check)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sway-Chan added a commit to Sway-Chan/FlowZ that referenced this pull request Jun 8, 2026
@dododook
dododook merged commit 2460caf into dododook:main Jun 8, 2026
@dododook

dododook commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Merged into main branch via local git merge, included in v3.5.0 release. Thank you for your contribution!

@Sway-Chan
Sway-Chan deleted the fix/naive-alpn branch June 15, 2026 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants