Skip to content

Fake Subscription Info Headers โ€‹

โฑ๏ธ 12 min ยท Level: Intermediate

Harmony injects synthetic subscription metadata into every HTTP response, enabling V2Ray/Xray-compatible clients to display plausible traffic quotas, expiry dates, and update intervals โ€” even though the worker operates without any real accounting backend. This mechanism is essential for client compatibility: most proxy clients (v2rayN, Nekobox, Sing-box, Clash Meta) parse the Subscription-Userinfo header to render usage dashboards, and will malfunction or refuse to import subscriptions that omit it entirely.

The Subscription-Userinfo Contract โ€‹

The V2Ray subscription convention defines a strict header format that clients parse to populate their UI. Harmony constructs this string via the generateCakeSubscriptionInfo function, which outputs a semicolon-delimited payload with four fields:

http
upload=<bytes>; download=<bytes>; total=<bytes>; expire=<unix_timestamp>
FieldTypeDescriptionHarmony Value
uploadInteger (bytes)Simulated uploaded trafficโ‰ˆ 50% of used
downloadInteger (bytes)Simulated downloaded trafficโ‰ˆ 50% of used
totalInteger (bytes)Total traffic quotatotal_TB ร— 1024โด
expireUnix timestampSubscription expiry timenow + expire_years ร— 365 ร— 86400

The upload and download values are split equally from the computed used total, presenting a balanced consumption profile that appears natural to client dashboards.

CAKE_SETTINGS โ€” Configuration Parameters โ€‹

The fake subscription parameters are centralized in the CAKE_SETTINGS constant, which controls the magnitude and dynamics of the simulated traffic data:

javascript
const CAKE_SETTINGS = {
  total_TB: 440,          // Total traffic quota in Terabytes
  base_GB: 88000,         // Base usage always shown (in Gigabytes)
  daily_growth_GB: 450,   // Daily traffic growth (in Gigabytes)
  expire_years: 2,        // Validity period in years (dynamic)
};
ParameterDefaultUnitPurpose
total_TB440TerabytesSets the apparent total quota โ€” large enough to never trigger "quota exceeded" warnings in clients
base_GB88,000GigabytesFloor value for used โ€” ensures the dashboard always shows meaningful consumption even at midnight
daily_growth_GB450GigabytesRate of apparent daily usage growth โ€” simulates gradual, realistic traffic accumulation
expire_years2YearsHow far into the future the expiry timestamp is set โ€” prevents "subscription expired" states

Time-Driven Dynamic Usage โ€‹

Time-Correlated Usage Curve

The critical design insight is that the reported usage is not static โ€” it advances throughout the day based on the current hour, creating the illusion of active, real-time consumption.

The function derives a dailyGrowth value proportional to the elapsed fraction of the day:

javascript
dailyGrowth = (currentHour / 24) ร— daily_growth_GB ร— 1024ยณ
used = base_GB ร— 1024ยณ + dailyGrowth

At midnight (hour 0), used equals the base value alone. By 23:59, used has climbed by nearly the full daily_growth_GB increment. This creates a monotonic, time-correlated usage curve that mimics real subscription behavior โ€” each client refresh within the same day returns a slightly higher usage than the last.

Response Header Assembly โ€‹

Once the subscription info string is generated, Harmony attaches it to the response alongside two additional standard headers that complete the subscription metadata envelope:

javascript
const headers = {
  "Content-Type": "text/plain; charset=utf-8",
  "Profile-Update-Interval": "6",
  "Subscription-Userinfo": subInfo,
};

if (profileTitle) {
  headers["Profile-Title"] = profileTitle;
}
HeaderValueClient Behavior
Content-Typetext/plain; charset=utf-8Signals base64-encoded payload encoding
Profile-Update-Interval6Client auto-refreshes subscription every 6 hours, ensuring fresh clean IPs are fetched periodically
Subscription-UserinfoDynamic (see above)Populates traffic dashboard, quota bars, and expiry display
Profile-TitleFrom ?name= param or #hash or "Harmony"Names the subscription profile in the client's sidebar โ€” derived from URL query parameter, fragment, or fallback default
Customizing the Profile Title

The Profile-Title resolution follows a priority chain: the name query parameter takes precedence, then the URL fragment (#), then the hardcoded default "Harmony". This allows users to customize the profile name directly in the subscription URL (e.g., https://worker.dev/?name=MyProfile).

Why "Fake" Headers Matter โ€‹

Architectural, Not Adversarial

The term "fake" here is architectural, not adversarial. Harmony is a stateless Cloudflare Worker โ€” it has no database, no user accounts, and no traffic accounting.

Without synthetic headers, clients would either:

  1. Refuse to import the subscription entirely (some clients validate the presence of Subscription-Userinfo before accepting).
  2. Display broken or empty dashboards with zeroed-out traffic bars and missing expiry dates.
  3. Fail to auto-refresh without Profile-Update-Interval, forcing manual updates to get fresh clean IPs.

The fake headers solve all three problems simultaneously with zero operational overhead โ€” no storage, no computation beyond simple arithmetic, and no external dependencies. The time-based growth function adds a thin layer of dynamism that prevents the dashboard from appearing frozen or suspiciously static.

Safe Customization

Modifying CAKE_SETTINGS is safe and has no side effects on proxy functionality โ€” the headers are purely informational for the client UI. Increase total_TB if your client warns about quota limits; decrease daily_growth_GB if the usage curve appears unrealistically steep for your use case.

Header Processing Flow in Context โ€‹

The fake subscription info generation is the final step in Harmony's request pipeline, executed after all VLESS configurations have been assembled and before the base64-encoded response is returned:

The subscription info headers are generated at line 1068, immediately after the VLESS configuration loop completes and immediately before the Response object is constructed. This ordering guarantees that the headers always reflect the current server time, even if IP fetching or link generation took several seconds.

Next Steps โ€‹

Learn how Harmony randomizes SNI casing to evade DPI-based filtering โ†’ .