MHSanaei/3x-ui · warning

vmess decode: %w

Error message

vmess decode: %w

What it means

Returned by parseVmess when the base64 payload after vmess:// decodes with neither padded StdEncoding nor RawURLEncoding. VMess share links carry base64(JSON); providers emit at least three variants (padded, unpadded, URL-safe), and this parser tries both before giving up. Everything before the JSON stage, so no protocol state is involved.

Source

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

	case strings.HasPrefix(link, "wireguard://"), strings.HasPrefix(link, "wg://"):
		return parseWireguard(link)
	default:
		return nil, fmt.Errorf("unsupported link scheme")
	}
}

// --- 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":

View on GitHub (pinned to ad32144c42)

Solutions

  1. Re-copy the full link from the source client and check it was not truncated (vmess payloads are long).
  2. Validate the payload yourself: strip 'vmess://', then try base64.RawURLEncoding and base64.StdEncoding with padding restored — if both fail, the payload is not base64 at all.
  3. If the payload is raw JSON, re-encode it to base64 or parse the JSON directly.
  4. Regenerate the link from the originating client rather than hand-repairing it.

Example fix

// before
raw, err := base64.StdEncoding.DecodeString(b64)

// after: tolerate all three common vmess encodings
s := strings.Map(func(r rune) rune {
    if r == '\n' || r == '\r' || r == ' ' { return -1 }
    return r
}, b64)
raw, err := base64.StdEncoding.DecodeString(padBase64(s))
if err != nil {
    raw, err = base64.RawURLEncoding.DecodeString(s)
}
Defensive patterns

Strategy: validation

Validate before calling

func isBase64ishPayload(link string) bool {
    s := strings.TrimPrefix(link, "vmess://")
    s = strings.Map(func(r rune) rune {
        if r == '\n' || r == '\r' || r == ' ' { return -1 }
        return r
    }, s)
    _, err1 := base64.StdEncoding.DecodeString(padBase64(s))
    _, err2 := base64.RawURLEncoding.DecodeString(s)
    return err1 == nil || err2 == nil
}

Try / catch

if _, err := link.ParseOutbound(l); err != nil {
    if strings.Contains(err.Error(), "vmess decode") {
        // payload is not base64: log the link, skip it, request a fresh copy from the provider
    }
}

Prevention

When it happens

Trigger: A vmess:// link whose payload is plain JSON (not base64); payload corrupted by URL-transport (spaces, +→%2B mishandling); missing padding combined with -/_ mixed into a single string; copy-paste truncation cutting the payload mid-base64.

Common situations: Links copied out of messengers/webpages where the base64 got percent-decoded or truncated; providers emitting base64 with newlines; homegrown generators that forget padding AND use URL-safe alphabet while the parser only tolerates one deviation at a time.

Related errors


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