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
- Ensure the target URL is absolute with scheme and host: 'https://host/path' (HTTP) or 'wss://host/path' (WS).
- Trim whitespace/newlines from the URL string before base64-encoding.
- 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
- Validate the target is an absolute http(s)/ws(s) URL with a host before encoding.
- Trim whitespace/newlines from the URL prior to base64.
- Percent-encode non-ASCII URL components before encoding.
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
- missing query param [u]
- decode [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/bbfa86966202c9ad.
Report an issue: GitHub.