CloakHQ/CloakBrowser · warning

[cloakbrowser] Malformed SOCKS5 proxy URL, passing through u

Error message

[cloakbrowser] Malformed SOCKS5 proxy URL, passing through unchanged: invalid port

What it means

The SOCKS5 proxy URL normalizer found a non-numeric port segment (e.g. socks5://user:pass@host:abc) and cannot parse it safely. Rather than mangling the URL, it logs this warning and returns the string unchanged, so whatever you passed is handed to Chromium as-is and will likely fail at connection time.

Source

Thrown at js/src/proxy.ts:127

  // Python urlparse's rpartition('@') behavior.
  const schemeMatch = urlStr.match(/^([a-z][a-z0-9+\-.]*):\/\/(.*)$/i);
  if (!schemeMatch) return urlStr;
  const [, scheme, rest] = schemeMatch;
  const hostStart = rest.search(/[/?#]/);
  const authority = hostStart === -1 ? rest : rest.slice(0, hostStart);
  const suffix = hostStart === -1 ? "" : rest.slice(hostStart);
  const atIdx = authority.lastIndexOf("@");
  if (atIdx === -1) return urlStr;  // no creds
  const userinfo = authority.slice(0, atIdx);
  const hostPart = authority.slice(atIdx + 1);
  // Validate port (matches Python's urlparse().port ValueError guard).
  // Extract port after last ':' — but skip IPv6 brackets (e.g. [::1]:1080).
  const bracketEnd = hostPart.lastIndexOf("]");
  const portColonIdx = hostPart.indexOf(":", Math.max(bracketEnd, 0));
  if (portColonIdx !== -1) {
    const portStr = hostPart.slice(portColonIdx + 1);
    if (portStr && !/^\d+$/.test(portStr)) {
      console.warn(`[cloakbrowser] Malformed SOCKS5 proxy URL, passing through unchanged: invalid port`);
      return urlStr;
    }
  }
  const hostAndRest = hostPart + suffix;
  const colonIdx = userinfo.indexOf(":");
  const rawUserEnc = colonIdx === -1 ? userinfo : userinfo.slice(0, colonIdx);
  const hasPassword = colonIdx !== -1;
  const rawPassEnc = hasPassword ? userinfo.slice(colonIdx + 1) : "";
  try {
    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

View on GitHub (pinned to d6bad5de26)

Solutions

  1. Fix the proxy URL so the port is purely digits: socks5://user:pass@host:1080.
  2. Verify no trailing path, query, or whitespace after the port; strip the string before passing.
  3. If using IPv6, wrap the host in brackets: socks5://[::1]:1080.
  4. URL-encode credentials containing special characters (or the auto-encoder handles it once the port is valid).

Example fix

// before
const proxy = 'socks5://user:p@ss@proxy.example.com:10abc';

// after
const proxy = 'socks5://user:p%40ss@proxy.example.com:1080';
Defensive patterns

Strategy: validation

Validate before calling

function isValidSocksUrl(u: string): boolean {
  try {
    const parsed = new URL(u);
    if (!/^socks5h?:$/.test(parsed.protocol)) return false;
    return parsed.port === '' || /^\d+$/.test(parsed.port);
  } catch { return false; }
}
if (!isValidSocksUrl(proxy)) throw new Error(`bad SOCKS5 proxy URL: ${proxy}`);

Type guard

const isWellFormedSocksUrl = (u: string): boolean =>
  /^socks5h?:\/\/[^\s]+@?\[[^\]]+\]|[^:@\s]+:\d+(\/)?$/.test(u.trim());

Prevention

When it happens

Trigger: Passing proxy: 'socks5://host:1080x' or 'socks5://host:notaport' to resolveProxyConfig/launch. The regex /^\d+$/ on the substring after the last colon (post IPv6-bracket handling) fails, e.g. also 'socks5://host:1080/path' with a suffix misparsed as port.

Common situations: Typos in proxy strings, pasting URLs with trailing paths or whitespace, templating bugs that inject undefined into the port position, credentials containing ':' shifting the parse.

Understand the failure class

Related errors


AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28). Data as JSON: /api/errors/04328ac20e21ce81. Report an issue: GitHub.