Tencent/WeKnora · error
unsupported URL scheme: %s
Error message
unsupported URL scheme: %s
What it means
DownloadBytes only accepts absolute http:// or https:// URLs; anything else (ftp:, file:, ws:, or scheme-less strings) is rejected before any network activity. This guard ensures the function only performs HTTP GETs.
Source
Thrown at internal/utils/httputil.go:20
import (
"fmt"
"io"
"net/http"
"strings"
"time"
)
var defaultHTTPClient = NewSSRFSafeHTTPClient(SSRFSafeHTTPClientConfig{
Timeout: 60 * time.Second,
MaxRedirects: 10,
})
// DownloadBytes fetches the content at the given HTTP(S) URL and returns the
// raw bytes. It reuses a package-level http.Client with a 60-second timeout.
func DownloadBytes(url string) ([]byte, error) {
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
return nil, fmt.Errorf("unsupported URL scheme: %s", url)
}
if err := ValidateURLForSSRF(url); err != nil {
return nil, fmt.Errorf("URL rejected by SSRF policy: %w", err)
}
resp, err := defaultHTTPClient.Get(url)
if err != nil {
return nil, fmt.Errorf("HTTP GET: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP %d for %s", resp.StatusCode, url)
}
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read body: %w", err)
}
return data, nil
}View on GitHub (pinned to 988cbb0330)
Solutions
- Prefix the URL with https:// (or http://) before calling DownloadBytes
- For local files, read with os.ReadFile instead of DownloadBytes
- Normalize/complete the URL when it comes from config or user input
- If other schemes are needed, resolve them separately and hand DownloadBytes only the https endpoint
Example fix
// before
DownloadBytes("example.com/data.json")
// after
DownloadBytes("https://example.com/data.json") Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(raw)
if err != nil || (u.Scheme != "http" && u.Scheme != "https") {
return fmt.Errorf("must be an http(s) URL")
} Type guard
func isHTTPURL(raw string) bool {
u, err := url.Parse(raw)
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
} Try / catch
data, err := DownloadBytes(url)
if err != nil {
if strings.Contains(err.Error(), "unsupported URL scheme") {
// normalize URL or fall back to a file/scheme-specific reader
}
} Prevention
- Always store fully-qualified http(s) URLs in config
- Normalize scheme-less user input by defaulting to https://
- Use os.ReadFile for local files instead of a URL downloader
When it happens
Trigger: Calling DownloadBytes with a URL lacking an http(s) prefix: file:// paths, data: URIs, relative paths like "/api/x", hostnames without a scheme ("example.com/file"), or other schemes (ftp, s3).
Common situations: Passing a local file path expecting the helper to read disk, config storing scheme-less URLs, URLs taken from user input without normalization, or S3/blob-store URIs handed to a generic downloader.
Related errors
- create request: %w
- create request: %w
- failed to create request: %w
- failed to create request: %w
- failed to create Exa request: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/91d91768c8ee3366.
Report an issue: GitHub.