siyuan-note/siyuan · error
missing query param [u]
Error message
missing query param [u]
What it means
Returned by parseForwardProxyParams (network.go:351) when the `u` query parameter is absent or empty. The forward-proxy endpoints (httpProxy, wsProxy) require `u` to carry the base64(RawURLEncoding)-encoded target URL; without it there is no destination to proxy to, so the request is rejected with HTTP 400.
Source
Thrown at kernel/api/network.go:351
dialer := util.SSRFSafeDialer(timeout)
client := req.C()
client.SetTimeout(timeout)
client.SetDial(dialer.DialContext)
client.SetRedirectPolicy(req.MaxRedirectPolicy(3))
return client
}
// parseForwardProxyParams decodes the `u` and `h` query parameters.
//
// 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)View on GitHub (pinned to 251596fc0d)
Solutions
- Always include ?u=<base64rawurl(targetURL)> when calling the forward-proxy endpoints.
- Build the query with a helper that asserts `u` is non-empty before firing the request.
- Check that the target URL string is non-empty before base64-encoding it.
Example fix
// before
fetch(`/api/network/forwardProxy`)
// after
const u = btoa(targetUrl).replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'')
fetch(`/api/network/forwardProxy?u=${u}`) Defensive patterns
Strategy: validation
Validate before calling
// Build the proxy URL with a required non-empty target
function proxyUrl(target) {
if (!target) throw new Error('target URL required');
const u = base64UrlSafe(target);
return `/api/network/forwardProxy?u=${u}`;
} Try / catch
try { await fetch(proxyUrl(target)); }
catch (e) { if (/missing query param \[u\]/.test(e.msg)) { /* rebuild URL with u param */ } else throw e; } Prevention
- Centralize proxy-URL construction in one helper that asserts `u` is set.
- Unit-test the helper against empty/undefined target values.
- Treat a missing target as a programming error, not a retryable one.
When it happens
Trigger: Calling /api/network/forwardProxy (HTTP) or the WS proxy endpoint without ?u=... in the query string. parseForwardProxyParams at network.go:348 reads c.Query("u") and returns this error at line 351 when it equals "". httpProxy/wsProxy then respond with HTTP 400 (network.go:421, 478).
Common situations: Frontend/proxy client forgot to append the `u` parameter. The base64-encoded URL was computed into a different variable and not added to the request URL. A misrouted request hitting the proxy endpoint without the expected query contract.
Related errors
- decode [u] failed: %s
- parse [u] failed: %s
- decode [h] failed: %s
- parse [h] failed: %s
- parse [t] failed: %s
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/0f5786cfe8559a36.
Report an issue: GitHub.