MHSanaei/3x-ui · warning

vmess json: %w

Error message

vmess json: %w

What it means

Returned by parseVmess when the base64 payload decoded fine but json.Unmarshal into map[string]any fails — the bytes are not valid JSON. VMess links are base64(JSON objects); this error means the decoded content is something else (HTML error page, binary, plain-text host:port, or another layer of encoding). Field extraction cannot proceed.

Source

Thrown at internal/util/link/outbound.go:146

	}
}

// --- vmess ---

func parseVmess(link string) (*ParseResult, error) {
	b64 := strings.TrimPrefix(link, "vmess://")
	// vmess:// base64(json)
	raw, err := base64.StdEncoding.DecodeString(padBase64(b64))
	if err != nil {
		// Some providers use raw URL-safe
		raw, err = base64.RawURLEncoding.DecodeString(b64)
	}
	if err != nil {
		return nil, fmt.Errorf("vmess decode: %w", err)
	}
	var j map[string]any
	if err := json.Unmarshal(raw, &j); err != nil {
		return nil, fmt.Errorf("vmess json: %w", err)
	}

	identity := vmessIdentity(j)

	network := getString(j, "net", "tcp")
	security := "none"
	if tls, _ := j["tls"].(string); tls == "tls" {
		security = "tls"
	}
	stream := buildStream(network, security)

	// Map known fields (best effort, matching frontend parser coverage)
	switch network {
	case "ws":
		host, _ := j["host"].(string)
		setWS(stream, host, getString(j, "path", "/"))
	case "grpc":
		svc := getString(j, "path", "")

View on GitHub (pinned to ad32144c42)

Solutions

  1. Decode the payload manually (base64 → string) and LOOK at it — you will immediately see whether it is JSON, HTML, or binary.
  2. If it is double-encoded, base64-decode a second time before re-importing.
  3. If it is an HTML challenge page, re-fetch the subscription with the correct client headers or from a different network.
  4. Rebuild the link in the source client's export function instead of hand-assembling it.
Defensive patterns

Strategy: validation

Validate before calling

func hasVmessJSONPayload(link string) bool {
    s := strings.TrimPrefix(link, "vmess://")
    raw, err := base64.RawURLEncoding.DecodeString(strings.TrimRight(s, "="))
    if err != nil { raw, _ = base64.StdEncoding.DecodeString(padBase64(s)) }
    if len(raw) == 0 || raw[0] != '{' { return false }
    return json.Valid(raw)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "vmess json") {
    // decoded bytes were not JSON: likely an HTML error page or double-encoded payload; drop the entry
}

Prevention

When it happens

Trigger: Payload that was double-base64-encoded; a provider serving an HTML/cloudflare challenge page encoded as the 'link'; JSON with trailing garbage or BOM; a vmess link generated by a client that writes a v2 JSON-N format with comments/trailing commas.

Common situations: Subscription URLs fetched without a proper User-Agent returning wrapped error bodies; links forwarded through tools that mangled quotes; hand-built vmess links where someone base64'd the string twice.

Related errors


AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15). Data as JSON: /api/errors/554093d694476eba. Report an issue: GitHub.