siyuan-note/siyuan · error

parse [u] failed: %s

Error message

parse [u] failed: %s

What it means

Returned by parseForwardProxyParams (network.go:361) when the `u` parameter decoded from base64 is not a parseable request URI. After successful base64 decode, url.ParseRequestURI(string(uBytes)) at network.go:359 fails — typically because the decoded string is a relative path, malformed, or missing the scheme/host. The request is rejected with HTTP 400.

Source

Thrown at kernel/api/network.go:361

//
// Query params:
//   - `u`: RawURLEncoding base64 of the target URL string.
//   - `h`: RawURLEncoding base64 of a JSON object map[string][]string.
//   - `timeout`: The timeout for the request in nanoseconds.
func parseForwardProxyParams(c *gin.Context) (parsedURL *url.URL, headers *http.Header, timeout time.Duration, err error) {
	uParam := c.Query("u")
	if uParam == "" {
		err = fmt.Errorf("missing query param [u]")
		return
	}
	uBytes, decErr := base64.RawURLEncoding.DecodeString(uParam)
	if decErr != nil {
		err = fmt.Errorf("decode [u] failed: %s", decErr.Error())
		return
	}
	parsedURL, err = url.ParseRequestURI(string(uBytes))
	if err != nil {
		err = fmt.Errorf("parse [u] failed: %s", err.Error())
		return
	}

	h := http.Header{}
	headers = &h
	hParam := c.Query("h")
	if hParam != "" {
		hBytes, decErr := base64.RawURLEncoding.DecodeString(hParam)
		if decErr != nil {
			err = fmt.Errorf("decode [h] failed: %s", decErr.Error())
			return
		}
		var record map[string][]string
		if jsonErr := json.Unmarshal(hBytes, &record); jsonErr != nil {
			err = fmt.Errorf("parse [h] failed: %s", jsonErr.Error())
			return
		}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Ensure the target URL is absolute with scheme and host: 'https://host/path' (HTTP) or 'wss://host/path' (WS).
  2. Trim whitespace/newlines from the URL string before base64-encoding.
  3. Percent-encode any non-ASCII components of the URL prior to encoding.

Example fix

// before
const u = encode('example.com/api') // no scheme
// after
const u = encode('https://example.com/api')
Defensive patterns

Strategy: validation

Validate before calling

// Require an absolute URL with scheme+host
function validTarget(u) { try { const p = new URL(u); return ['http:','https:','ws:','wss:'].includes(p.protocol) && !!p.host; } catch { return false; } }

Prevention

When it happens

Trigger: Decoded `u` is something like '/path/to/thing' (no scheme/host), 'example.com' (no scheme), contains illegal characters/spaces, or is a fragment-only/empty string. ParseRequestURI is stricter than Parse and demands an absolute request-URI form.

Common situations: Client decoded a relative URL. Whitespace accidentally included in the base64 source. Target URL built by string concatenation that dropped the scheme. Unicode/IRI that was not percent-encoded before base64.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/bbfa86966202c9ad. Report an issue: GitHub.