Skip to content

Ports and ALPN Settings ​

⏱️ 8 min · Level: Advanced

Ports and ALPN (Application-Layer Protocol Negotiation) are two tightly coupled parameters that define how VLESS connections traverse Cloudflare's edge network. Ports determine the transport entry point, while ALPN negotiates the application protocol during the TLS handshake. In Harmony, both are defined per configuration group and carry strict compatibility constraints — a mismatch between port type and TLS/ALPN settings will produce non-functional configurations.

Cloudflare Proxy Port Landscape ​

Cloudflare's reverse proxy only forwards traffic on a fixed set of ports. Any port outside these sets is silently dropped at the edge, making the connection unreachable. Harmony exposes these as per-group arrays from which a single port is randomly selected at subscription generation time, distributing clients across multiple entry points to reduce single-port congestion and detection surface.

CategoryPortsProtocol StackCloudflare Behavior
TLS/HTTPS443, 8443, 2053, 2083, 2087, 2096TCP → TLS → WebSocketFull TLS termination; ALPN negotiation occurs
HTTP/TCP80, 8080, 8880, 2052, 2082, 2086, 2095TCP → WebSocketNo TLS; plaintext WebSocket upgrade

NOTE

These six TLS ports and seven HTTP ports are the complete set of ports Cloudflare proxies for Workers traffic. No other ports will route to your Worker, regardless of configuration.

Port Configuration Per Group ​

Each group in USER_SETTINGS.groups declares a ports array. The default configuration demonstrates the canonical port assignment strategy:

Group 1 — TLS (Harmonyᵀᴸˢ): All six Cloudflare TLS ports are listed, maximizing port diversity for TLS-terminated connections.

javascript
ports: ["443", "8443", "2053", "2083", "2087", "2096"],

Group 2 — Non-TLS/TCP (Harmonyᵀᶜᴾ): All seven Cloudflare HTTP ports are listed for plaintext WebSocket connections. This group is Workers-only — Cloudflare Pages does not support non-TLS routing.

javascript
ports: ["80", "8080", "8880", "2052", "2082", "2086", "2095"],

Group 3 — Alternative TLS (Harmonyᴱᴹˢ): A minimal two-port subset (443, 2053) is used, demonstrating that you need not include every available port — a focused subset can be preferable for environments where only standard ports are allowed through firewalls.

javascript
ports: ["443", "2053"],

TIP

Port values are stored as strings, not numbers. This is intentional — the VLESS URI template requires the port as a string segment in vless://uuid@ip:port?params#name, and string storage avoids implicit type coercion issues during link assembly.

Random Port Selection at Runtime ​

Port selection is non-deterministic per configuration link. During createVlessLink execution, one port is randomly sampled from the group's array:

javascript
const randomPort = group.ports[Math.floor(Math.random() * group.ports.length)];

This means that across ipCount configurations generated per group, each VLESS link independently picks a port. With six TLS ports and ipCount: 10, you'll get an approximately uniform distribution — roughly 1–2 configs per port per subscription refresh. This randomization serves two purposes: load distribution across Cloudflare edge entry points, and detection resistance by avoiding a single static port fingerprint across all configs.

The selected port is embedded directly into the VLESS URI:

javascript
return `vless://${settings.uuid}@${ip}:${randomPort}?${queryParams.toString()}#${ps}`;

ALPN Protocol Negotiation ​

ALPN is a TLS extension that lets the client and server agree on the application protocol during the handshake, before any application data flows. For VLESS-over-WebSocket configurations, the only viable ALPN value is http/1.1, because WebSocket upgrade requires an HTTP/1.1 request-response cycle. HTTP/2 and HTTP/3 ALPN values are incompatible with the WebSocket upgrade mechanism.

ALPN Configuration Per Group ​

Grouptlsalpn ValueRationale
Harmonyᵀᴸˢtrue"http/1.1"TLS group; WebSocket requires HTTP/1.1 negotiation
Harmonyᵀᶜᴾfalse"" (empty)Non-TLS group; no TLS handshake → no ALPN negotiation possible
Harmonyᴱᴹˢtrue"http/1.1"TLS group; same WebSocket constraint

Conditional ALPN Injection ​

ALPN is not unconditionally written into every VLESS link. The createVlessLink function applies it only when both conditions are met:

javascript
if (group.tls) {
    queryParams.set("security", "tls");
    // ... SNI handling ...
    if (group.alpn) {
        queryParams.set("alpn", group.alpn);
    }
}

⚠️ DOUBLE-GATE CHECK

This double-gate — group.tls === true and group.alpn is truthy — ensures that non-TLS groups never emit an alpn query parameter. An ALPN value on a non-TLS connection is semantically meaningless (there is no TLS handshake to carry it) and will cause V2Ray/Xray cores to reject the configuration.

Port-TLS-ALPN Compatibility Matrix ​

The three parameters form a strict invariant. Violating any constraint produces a broken configuration:

Port CategoryRequired tlsRequired alpnValid alpn ValuesInvalid alpn Values
TLS ports (443, 8443, 2053, 2083, 2087, 2096)trueMust be set"http/1.1""", "h2", "h3"
HTTP ports (80, 8080, 8880, 2052, 2082, 2086, 2095)falseMust be empty""Any non-empty string

⚠️ COMMON MISCONFIGURATION

When customizing groups, always validate the invariant: TLS ports require tls: true + non-empty alpn, and HTTP ports require tls: false + empty alpn. A common misconfiguration is adding "443" to a non-TLS group's port array — this will produce links that appear valid but cannot establish connections.

Customizing Port Lists ​

Port arrays are fully editable. Common customization scenarios:

Reducing port surface: Some network environments block non-standard ports. Restricting to the most commonly allowed ports minimizes connection failures:

javascript
// Conservative TLS — only universally allowed ports
ports: ["443", "8443"],
alpn: "http/1.1",

// Conservative HTTP — only the standard HTTP port
ports: ["80", "8080"],
alpn: "",

Single-port locking: For environments with strict egress firewall rules where only one port is permitted:

javascript
// Lock to port 443 only
ports: ["443"],
alpn: "http/1.1",

NOTE

When a single port is specified, the random selection at line 1099 always returns that port, effectively making it static across all generated configs in the group.

Adding redundancy with duplicate ports: You can weight port selection by duplicating entries. With ports: ["443", "443", "8443"], approximately 67% of configs will use port 443 and 33% will use port 8443.

ALPN Beyond http/1.1 ​

While "http/1.1" is the only functional ALPN value for VLESS-WebSocket configurations in Harmony, the V2Ray/Xray core supports additional ALPN values for other transport types. The following table documents the full ALPN landscape for reference, but only http/1.1 is compatible with Harmony's WebSocket transport:

ALPN ValueTransport CompatibilityWorks in HarmonyReason
http/1.1WebSocket over TLS✅WebSocket upgrade requires HTTP/1.1 framing
h2gRPC over TLS❌Harmony uses type: ws, not type: grpc
h3QUIC-based transport❌Cloudflare Workers do not proxy QUIC to origin
"" (empty)Non-TLS connections✅ (non-TLS groups only)No TLS handshake → no ALPN negotiation

⚠️ INCOMPATIBILITY WARNING

Attempting to set alpn: "h2" in a Harmony group will produce VLESS links that parse correctly but fail at connection time — the Xray core will negotiate HTTP/2 with Cloudflare's edge, which cannot upgrade an HTTP/2 stream to WebSocket.

Complete Group Parameter Flow ​

The following diagram shows how ports and alpn flow from group definition through to the final VLESS URI:

Next Steps ​

Now that you understand port and ALPN constraints, explore how clean IPs are sourced for these configurations in , or learn about the VLESS link assembly process in .