Aug 27, 2026 · Protocols · About 10 min

Shadowrocket Share Link Formats: ss://, vmess://, vless:// and trojan:// Explained

Learn how ss://, vmess://, vless:// and trojan:// links are structured, and how single-node links differ from subscription URLs. All examples use dummy values.

At a glance

A single-node share link stores connection parameters; a subscription URL points to a collection of nodes that can be fetched again. This guide is for users who already have a provider and subscription and need to verify the import format. Identify the link type, check its encoding, address, port and TLS fields, then distinguish a successful import from a working connection and correctly applied rules. All domains, passwords, UUIDs and tokens are dummy values and cannot be used to connect.

[URI] First, distinguish a parameter link from a subscription URL

A single-node entry and a subscription group in Shadowrocket are different kinds of data. Share links beginning with ss://, vmess://, vless:// or trojan:// usually contain the connection parameters for one node. A subscription URL beginning with https:// requires the app to request data from a server and create a node list from the response. Link length alone does not tell you which type it is.

4 types
URI schemes covered in this guide: ss / vmess / vless / trojan
8388
Example port for Shadowsocks in this guide; not a requirement
443
Example TLS port in this guide; the actual value depends on the existing service parameters

A share link is a snapshot of connection parameters. If the remote address or password changes after import, the standalone entry does not update automatically. A subscription URL preserves a retrieval endpoint, so you can fetch the current list when you update it. However, it does not provide continuous push updates: changes depend on the response and whether the update succeeds.

[Encoding] Base64, percent-encoding and delimiters

Base64 is encoding, not encryption. Anyone with a share link can usually recover its password or UUID; a token in a subscription URL should also be treated as a credential. Do not submit full links, QR codes or decoded contents to unfamiliar websites. When troubleshooting, note only whether a field is present and redact sensitive values.

Symbol or encodingCommon useHow to check
://Separates the scheme from the content that followsKeep the ASCII symbol as-is; do not add spaces or line breaks.
@Separates credentials from the host sectionA literal @ in a password usually needs to be written as %40.
? and &Introduces and separates query parametersCopy the original link. Do not mistake & in webpage source for a parameter delimiter.
#Introduces a fragment, often used for a remarkSpaces in a remark can be encoded as %20; they are not used for server authentication.
Base64Wraps credentials, JSON or a subscription responseDistinguish the standard and URL-safe alphabets; do not blindly decode the entire URI.

Standard Base64 may contain +, / and a trailing =. URL-safe Base64 may use - and _, and some implementations omit the trailing padding. Percent-encoding is a separate syntax layer: for example, %2F represents a slash. These encodings are not interchangeable, and not every + should be replaced with a space.

[Check]

Locate the encoded section for the specific format, then decode it once. Double-encoding %2F as %252F, or encoding every delimiter in the URI, changes how it is parsed.

[Shadowsocks] Credentials and server fields in ss://

A common SIP002 format encodes the encryption method and password in the userinfo, while leaving the server address and port readable. The Base64 content in this example is aes-128-gcm:test, where test is only a demo password. Port 8388 is an example, not a required Shadowsocks port.

ss://[email protected]:8388#Demo%20SS
  1. scheme: ss specifies Shadowsocks; do not change it to another protocol after import.
  2. userinfo: Decoding gives the encryption method aes-128-gcm and the password test, separated by a colon.
  3. Host and port: example.com:8388 is the connection target. In actual use, it must match the parameters you already have.
  4. Remark: Demo%20SS decodes to Demo SS and is only used to identify the entry.

Older share formats may also Base64-encode the entire section containing the host and port, so not every ss:// link will show a readable @example.com. Links with a plugin parameter also require checking the plugin and its options; identifying Shadowsocks does not guarantee that the additional transport parameters are complete. IPv6 address literals are usually enclosed in square brackets in the host section to distinguish them from the colon that separates the port.

[VMess] Base64-encoded JSON commonly used in vmess:// links

A common vmess:// share format places Base64-encoded JSON after the scheme. The example below shows the decoded content, not a complete URI ready to paste for import. Its dummy domain and UUID are included to illustrate the purpose of each field.

{
  "v": "2",
  "ps": "Demo VMess",
  "add": "example.com",
  "port": "443",
  "id": "00000000-0000-4000-8000-000000000001",
  "aid": "0",
  "scy": "auto",
  "net": "ws",
  "type": "none",
  "host": "example.com",
  "path": "/demo",
  "tls": "tls",
  "sni": "example.com"
}

In the JSON, v is a share-format field, not the Shadowrocket app version; ps is a remark, not a password. Export tools may use different sets of fields, so this example is not the only valid VMess link structure. If the protocol is correct after import but the path is missing, check the transport parameters in the node editor rather than only checking the UUID.

[VLESS / Trojan] Credentials and TLS in readable URIs

Common VLESS and Trojan share formats use readable URI structures, but the credentials before @ mean different things: VLESS usually uses a UUID, while Trojan usually uses a password. VLESS does not itself provide transport encryption equivalent to TLS. In this example, security=tls specifies TLS; do not infer the connection’s security settings from the protocol name alone.

vless://[email protected]:443?encryption=none&security=tls&type=ws&host=example.com&path=%2Fdemo&sni=example.com#Demo%20VLESS

trojan://demo%[email protected]:443?security=tls&type=tcp&sni=example.com#Demo%20Trojan

Check both layers: authentication and transport

Authentication and connection target
  • VLESS UUID: This example uses a complete UUID for demonstration.
  • Trojan password: demo%40pass decodes to demo@pass.
  • Both examples connect to example.com:443; the port is not fixed.
TLS and transport
  • sni specifies the server name used in the TLS handshake.
  • For the type=ws example, also check the Host and /demo path.
  • Do not copy WebSocket path settings to type=tcp.

The connection address, TLS SNI and WebSocket Host can serve different purposes. Whether they should match depends on the existing parameters; do not replace them all just because they look like domain names.

In the VLESS example, encryption=none does not mean TLS is disabled; it is a separate layer from security=tls. The Trojan example’s password contains a special character, so @ is percent-encoded. Do not remove the encoding just to make the link “look right,” and do not hide an SNI or certificate-name mismatch by disabling certificate verification.

Query parameter names and support for extensions can vary between share implementations. If an existing link includes additional fields, keep their values and check each corresponding setting in the Shadowrocket node editor after import. Seeing an entry in the list does not prove that all its parameters were accepted.

[Subscribe] Handle single-node imports and subscription updates separately

The subscription URL below illustrates URL structure only; it is not a working service endpoint. token=xxxx is an obvious dummy value, and tokens in real URLs should not be shared. A regular webpage URL may also begin with HTTPS; it can generate a node list only if its response meets the subscription parser’s requirements.

https://example.com/sub?token=xxxx
  1. Existing single-node link: Copy the complete URI and use the app’s link import option. After import, open the node’s edit screen from Home and check its type, address, port and transport parameters.
  2. Existing subscription URL: Go to Home → Add Server, select Subscribe, enter the subscription URL you already have and save it. Then check the subscription group and its node list.
  3. Existing service parameters have changed: Update the subscription group. For a standalone imported entry, import the new link or edit it manually using the new parameters.
  4. Local edits before an update: Save any parameters you want to keep first. A subscription update may regenerate nodes managed by the server, so do not assume local name or field edits will permanently override them.

A subscription response may contain a set of share links or text encoded as a whole in Base64. Encoding the subscription response and encoding an individual node are two separate layers: after decoding the outer layer, a vmess:// link inside may still contain its own Base64 JSON. Do not treat the subscription body as a password field or join a decoded set of links into a single URI.

Bottom line: When remote parameters change, first check where the entry came from

If it belongs to a Subscribe group, update it and check the returned list. If it is a standalone node, use the new share link. Toggling the connection repeatedly will not fetch updated parameters for a standalone URI.

[Routing] After import, verify the connection and rules

Importing a link saves connection parameters; it does not determine how every request is routed. Use Home to view nodes and connection status, Config to manage configurations, and Settings to adjust app settings. When troubleshooting, first check the selected node on Home, then verify Global Routing. An entry appearing in the list does not prove that requests are going through it.

Global Routing → Config

Recommended

To use a connection with your existing rules, select Config and check the active configuration. Rules are typically matched in order, and the final route depends on the policy that matches.

Best for: Checking everyday rule-based routing with an existing configuration

Global Routing → Proxy

Use this to temporarily check the proxy route and avoid mistaking a Direct match in Config for an unavailable node. Restore your usual mode when testing is complete.

Best for: Isolating the effect of rules and checking the selected node’s connection

Global Routing → Direct

This uses a direct route, so it cannot confirm that an imported proxy node works. Opening a webpage directly and successfully authenticating with that node are two different things.

Best for: Comparing direct access on your local network

Check Scene in Global Routing against the scenes you have configured; it is not interchangeable with Proxy or Config. The [Rule] excerpt below illustrates rule order only. It is not a complete configuration and should not replace an existing file. The domain and IP range are examples.

[Rule]
DOMAIN-SUFFIX,example.com,PROXY
IP-CIDR,192.0.2.0/24,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY

Settings → On Demand manages conditional connection behavior; it does not replace node authentication or fix a malformed URI. If you only need to verify an import, first confirm that a connection has been established and the correct node is selected. Then check the automatic connection conditions, changing only one variable at a time.

[Troubleshooting] Common questions about parsing and updating share links

Why wasn’t a node imported when I copied a link?

First check that the link starts with a complete scheme, then make sure the copied text does not include instructions, quotation marks, spaces or line breaks added by a messaging app. Copy one complete URI only. If you were given an HTTPS subscription URL, process it through Subscribe instead of pasting it as a single-node password.

The node appears, but why won’t it connect?

On Home, check the selected node’s address, port and authentication details, then verify TLS SNI, WebSocket Host and path. Next, check Global Routing; results in Direct mode cannot verify a proxy node. If the parameters match the service details you have, check the server status rather than randomly changing the protocol type.

The subscription is empty after an update. Can I still use the old links?

Keep the original subscription URL, check that its token and query parameters are complete, then confirm that the response contains node data rather than a login page, error page or empty response. Whether old nodes still connect depends on whether the server continues to accept the old parameters; an empty list alone does not tell you.

If I share one node from a subscription, will it update automatically for the recipient?

Usually not. Sharing a single node gives the recipient a snapshot of its current parameters; it does not include the original subscription’s update relationship. Only saving and updating the corresponding subscription URL can retrieve changes to the remote list. Before sharing, make sure you are allowed to disclose its authentication details.

Will changing the name after # in a link affect the connection?

In the URI formats shown here, the fragment is used for a remark. Changing it does not replace the server address, password or UUID. If the link no longer imports, check whether you accidentally deleted an earlier parameter or left a special character in the remark unencoded as a delimiter.

Check in this order: link type → encoding integrity → authentication fields → transport and TLS → current routing mode. Change one item at a time and record its original value. This helps distinguish a parsing error, server rejection, TLS verification failure and rules that bypass the proxy—without masking the underlying issue by repeatedly re-importing the link.

Verify Shadowrocket on the App Store