Objects

What you can tap in the list, and what only stores an address, are not the same thing.

With the switch on, only the currently highlighted record is used. Subscribe is a container: it holds a URL; child records appear after a refresh. A rule configuration is a third object, alongside the first two; they do not replace each other.

  1. 01Three objects
  2. 02Record
  3. 03URI and scan
  4. 04Container: save and refresh
  5. 05Many rows, one used
  6. 06Treat URLs as secrets

01

The three objects do not replace each other

Shadowrocket Type list: Subscribe is a container; the other types are records
When adding, Type Subscribe is a container; the other types are records. From the App Store listing; your device build may differ.

What you see in the home list is usually records and containers. The rule file lives in another entry. Changing the highlighted row does not change rules; changing rules does not change the highlighted row; refreshing a container does not change FINAL. Treat the three as “three copies from one import” and every later isolation will scramble.

Record

One exit

Address, port, protocol, credentials, transport. Can be highlighted. There is no “refresh” — if the remote changes parameters, this local row does not update itself; you edit it or delete and recreate.

Container

One URL

Save only writes the address; the child-record set can be empty at that moment. Refresh is what fetches. On failure the last successful set is kept. When the URL dies, the client cannot repair it.

02

Record: fields must be the same set as the remote

The add entry is split by type. Type is this record’s identity, not a label. Choosing Trojan with a Shadowsocks password will save; the tunnel handshake will fail. UUID, password, cipher, alterId and other credential fields must match the far end; “looks close enough” is not enough.

Transport belongs to the record itself, not an optional extra. The remote uses WebSocket and local stays on TCP; the remote requires TLS and local turned it off; path, Host, gRPC service name, REALITY public key and short ID filled as another set — all save, none handshake. When isolating, treat “protocol type” and “transport” as two checks; do not only verify address and port.

SNI / peer hostname, whether to skip certificate verification, and fingerprint decide whether TLS can finish. Certificates also depend on system time: if time is not set automatically, every TLS record fails together, and swapping a row does not help. See Data.

A record describes one exit. It does not contain rules, and it does not contain “after connect, automatically switch to another.” The millisecond number from the list probe only says whether this hop probes right now; see the Data page.

Address
Peer hostname or IP. Pasting a whole URI here is usually not parsed as ss://; it becomes an illegal hostname.
Port
The port the peer listens on. Filling a web port or an admin-panel port means the handshake target is not the proxy process.
Auth
Password, UUID, username — the set that type requires. One field extra, one field missing, or copied from another type, is still an auth failure.
Transport
TCP, WebSocket, gRPC, and so on, plus path and Host. It sits beside type, not under “advanced, skippable.”

03

A URI is one packed line, not an address bar

ss://, vmess://, trojan://, vless:// pack type, credentials, and transport into one line. Pasting the whole line into the add entry makes fewer UUID typos than copying by hand. Pasting the whole line into the single “server address” field is usually not parsed as a URI.

A scanned code may be one record, a container URL, or a configuration download. After save, see whether it can be highlighted: if it can, and the fields are host and port, it is a record; if you can only expand it and inside is a URL, with child records waiting on refresh, it is a container; if it landed in the configuration list rather than the server list, it is a configuration.

Scanning the same code twice can create two identical records. While connected, only the highlighted one is used; duplicate rows do not stack bandwidth, they only raise the chance of selecting the wrong one.

04

Container: save and refresh are two steps

Save writes the URL onto the device. This step does not download child records. Right after save the list can look empty; for a container that is normal, not “the subscription is broken.”

Refresh fetches by URL. On success, returned content creates or replaces child records, which can then be highlighted like ordinary records. On failure it will not wipe child records that are already there — you still see the last successful set, which may be stale, but it is still there.

Refresh on open and background refresh both repeat “refresh.” Whether background can run also depends on the system allowing Background App Refresh, and on Low Power Mode. That is a System limit, not a container switch you left off.

The refresh request follows the network path of that moment. If the switch is sitting on a dead record, the refresh itself can fail. Switching policy to Direct, or turning the switch off, isolates the path; it does not repair the URL. If the URL returns 404, 401, or an empty file, the client can only report failure; it cannot renew the link on the far end.

Opening a subscription URL in a browser often yields something that is not a web page. It is for the client to parse. If the browser can download bytes, the path is up and the link is still alive; if the browser cannot open it either, the problem is the network or the link, not Shadowrocket’s parser.

Do not treat two kinds of refresh as one operation

Refreshing a server container updates child records in the list. Refreshing a rule / configuration subscription updates the list file. The URLs can look alike; the objects are not the same. Refreshing a container does not change FINAL; refreshing rules does not change the highlighted row.

05

Many rows, one used

The list allows many records and many containers. While connected, only the currently highlighted record is used. Two containers do not load-balance, and do not auto-select “the row with the smallest probe number.” However small the probe, if it is not highlighted, the switch will not use it.

Deleting a container usually deletes the child records it generated. If the current highlight belonged to that container, pick another row before you flip the switch again. Manually added records do not disappear because some container was deleted; conversely, rows refreshed from a container are not a copy that can live forever apart from the URL — the next refresh may rewrite or remove them.

Manually copying a row out of a container into a standalone record means later refreshes will not touch that copy. If the remote changes port, the copy does not follow; you edit it yourself. That is the tradeoff between “freeze a row” and “keep following the URL.”

06

Treat URLs as secrets

Many containers put a token in the path. Appearing in a screenshot, a group file, a public drive, or browser history is handing over access to the child records. The client will not revoke a leaked URL for you, and will not tell the remote to rotate the link.

Exported backups, and files you send to another device, also contain credentials. Treat them as secrets; do not forward them as ordinary documents. iCloud sync uses your Apple ID, not the developer’s servers; the developer does not hold your list. See Config.

The app cannot extend a URL’s lifetime, pay a server bill, or turn a failed handshake into a working record. The System chapter files these under things the app cannot do, not under a missing setting.