projectdiscovery/nuclei · warning
parse target: %w
Error message
parse target: %w
What it means
normalizeTarget failed at url.Parse: the target contains '://' but is not a parseable URL. Go's url.Parse rejects control characters in URLs, invalid percent-escapes ('%zz'), and malformed hosts such as an unclosed IPv6 bracket. The target string handed to a goexec-backed client (wmi.Client, etc.) is malformed rather than a plain host or host:port.
Source
Thrown at pkg/js/libs/goexec/target.go:18
package goexec
import (
"fmt"
"net"
"net/url"
"strings"
)
func normalizeTarget(target string) (string, error) {
target = strings.TrimSpace(target)
if target == "" {
return "", ErrMissingTarget
}
if strings.Contains(target, "://") {
parsed, err := url.Parse(target)
if err != nil {
return "", fmt.Errorf("parse target: %w", err)
}
target = parsed.Host
}
if host, port, err := net.SplitHostPort(target); err == nil {
if host == "" {
return "", ErrMissingTarget
}
if port == "" {
return host, nil
}
return net.JoinHostPort(host, port), nil
}
if strings.HasPrefix(target, "[") && strings.HasSuffix(target, "]") {
target = strings.TrimPrefix(strings.TrimSuffix(target, "]"), "[")
if target == "" {
return "", ErrMissingTarget
}
}View on GitHub (pinned to 265b3a3dec)
Solutions
- Pass a plain host or host:port ('dc01', '10.0.0.5:445') with no scheme.
- Strip the scheme client-side: use new URL(target).host before constructing.
- Trim whitespace and reject control characters in targets before use.
- For IPv6, use bracketed host or host:port forms that net.SplitHostPort handles.
Example fix
// before
const c = new wmi.Client('smb://dc01 acme/', auth); // parse target: invalid control character / missing parts
// after
const raw = 'smb://dc01 acme/';
const host = new URL(raw.replace(/\s+/g, '')).host || new URL(raw.replace(/\s+/g, '')).hostname;
const c = new wmi.Client(host, auth); Defensive patterns
Strategy: validation
Validate before calling
// normalize the target client-side before constructing wmi.Client
function toHostPort(target) {
let t = String(target || '').trim();
if (t.includes('://')) {
const u = new URL(t); // throws on malformed URLs — catch early
t = u.host || u.hostname;
}
if (/[ -]/.test(t)) throw new Error('control characters in target');
return t; // plain host or host:port
}
const safeTarget = toHostPort(rawTarget); Type guard
/** @param {unknown} t @returns {boolean} */
function isParsableTarget(t) {
if (typeof t !== 'string') return false;
const s = t.trim();
if (s === '' || /[ -]/.test(s)) return false;
if (!s.includes('://')) return true;
try { new URL(s); return true; } catch (_) { return false; }
} Prevention
- Pass plain host or host:port to goexec-backed clients; strip schemes yourself.
- Trim whitespace and reject control characters when ingesting targets from files/input lists.
- Close IPv6 brackets properly or omit them with a bare host.
When it happens
Trigger: new wmi.Client('smb://dc01 acme/', auth) (space in authority), 'https://[2001:db8::1' (missing ']'), control bytes from untrusted input lists, or '%zz' escape sequences — anything with a scheme separator that fails strict URL parsing.
Common situations: Templates concatenating unvalidated input into the target; IPv6 literals copied without brackets closure; copy-paste targets with whitespace or CR.
Related errors
- invalid host or port
- invalid host or port
- file path cannot be empty
- invalid number of recipients: required 1, got %d
- invalid host or port
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/72b1137df8243304.
Report an issue: GitHub.