CloakHQ/CloakBrowser · warning
[cloakbrowser] Could not normalize SOCKS5 proxy URL, passing
Error message
[cloakbrowser] Could not normalize SOCKS5 proxy URL, passing through unchanged: ${(e as Error).message} What it means
An unexpected exception escaped while normalizing a SOCKS5 proxy URL (e.g. a malformed URL that made built-ins like decodeURIComponent/URI encoding throw). The function catches it, logs the underlying message, and passes your original string through untouched — so the raw URL goes to Chromium and may fail later.
Source
Thrown at js/src/proxy.ts:155
const encUser = rawUserEnc ? encodeURIComponent(lenientDecodeURIComponent(rawUserEnc)) : "";
const encPass = hasPassword
? (rawPassEnc ? encodeURIComponent(lenientDecodeURIComponent(rawPassEnc)) : "")
: null;
const normalized = assembleSocksUrl(scheme, encUser, encPass, hostAndRest);
// Compare credentials, not the full URL: keeps the log condition focused
// on real encoding work, not cosmetic differences (parity with the Python
// implementation, which has to skip urlparse's hostname lowercasing).
const credsChanged = encUser !== rawUserEnc
|| (hasPassword ? encPass !== rawPassEnc : false);
if (credsChanged) {
console.info(
"[cloakbrowser] Auto URL-encoded SOCKS5 proxy credentials (special " +
"characters detected). Pre-encode the URL to suppress this notice.",
);
}
return normalized;
} catch (e) {
console.warn(`[cloakbrowser] Could not normalize SOCKS5 proxy URL, passing through unchanged: ${(e as Error).message}`);
return urlStr;
}
}
function hasCredentials(proxy: string | ProxyDict): boolean {
if (typeof proxy === "string") return proxy.includes("@");
return !!proxy.username;
}
/**
* Reconstruct an HTTP(S) proxy URL with inline credentials from a proxy dict.
*/
export function reconstructHttpUrl(proxy: ProxyDict): string {
if (!proxy.username) return proxy.server;
const url = new URL(ensureProxyScheme(proxy.server));
url.username = encodeURIComponent(proxy.username);
if (proxy.password) url.password = encodeURIComponent(proxy.password);
return url.href.replace(/\/$/, "");View on GitHub (pinned to d6bad5de26)
Solutions
- Pre-encode the whole proxy URL yourself with encodeURIComponent on user/password parts (the warning for auto-encoding then disappears too).
- Validate/decode the URL before passing it: ensure it parses with new URL(...) and percent-sequences are valid.
- Check for stray whitespace/newlines around the value from env vars or .env files.
Example fix
// before
const proxy = `socks5://myuser:p@ss:w%ord@1.2.3.4:1080`;
// after
const u = encodeURIComponent('myuser');
const p = encodeURIComponent('p@ss:w%ord');
const proxy = `socks5://${u}:${p}@1.2.3.4:1080`; Defensive patterns
Strategy: validation
Validate before calling
function safeSocksUrl(user: string, pass: string, host: string, port: number): string {
return `socks5://${encodeURIComponent(user)}:${encodeURIComponent(pass)}@${host}:${port}`;
}
const proxy = safeSocksUrl('user', 'p@ss%', '1.2.3.4', 1080); // never throws in normalizer Type guard
const hasValidPercentEncoding = (u: string): boolean => { try { decodeURIComponent(u); return true; } catch { return false; } }; Prevention
- Always percent-encode credentials yourself; don't rely on the auto-encoder after an exception path.
- Reject proxy strings containing whitespace/control characters before passing them on.
- Unit-test proxy-URL construction against special-character credentials.
When it happens
Trigger: Passing a SOCKS5 URL with invalid percent-encoding (e.g. %ZZ in credentials), control characters, or other structural oddities that throw inside the try block of normalizeSocksStringUrl; the catch returns urlStr verbatim.
Common situations: Credentials with raw special characters ($, @, :, %, spaces) pasted from a proxy provider dashboard; double-encoded URLs; strings containing newlines from env vars or config files.
Related errors
- [cloakbrowser] Could not normalize HTTP proxy URL, passing t
- [cloakbrowser] Malformed SOCKS5 proxy URL, passing through u
- GeoIP resolution failed: could not discover the egress IP
- GeoIP resolution timed out after {timeout:0.0}s
- GeoIP resolution failed: could not discover the egress IP
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/4eb24fa6d0eade56.
Report an issue: GitHub.