projectdiscovery/nuclei · warning
VERSION option too short
Error message
VERSION option too short
What it means
The VERSION option carries exactly 4 bytes of data (major, minor, build high, build low) and the parser requires at least 4 bytes to fill MajorVersion/MinorVersion/BuildNumber. This error means the VERSION option's offset/length resolved to fewer than 4 bytes (a short length, or length 0 leaving data nil). It is wrapped with errNotMssql, so mssql.IsMssql yields false and mssql.FingerprintMssql yields 'not a mssql service: VERSION option too short'.
Source
Thrown at pkg/js/libs/mssql/fingerprint.go:235
if start < 8 || end > len(response) {
return out, fmt.Errorf("invalid PL option data range")
}
data = response[start:end]
}
tokens = append(tokens, optionToken{token: token, offset: offset, length: length, data: data})
position += 5
}
if position >= len(response) || response[position] != tdsTerminator {
return out, fmt.Errorf("missing PL option terminator")
}
if len(tokens) == 0 {
return out, fmt.Errorf("no PL option tokens")
}
if tokens[0].token != plTokenVersion {
return out, fmt.Errorf("first PL option must be VERSION")
}
if len(tokens[0].data) < 4 {
return out, fmt.Errorf("VERSION option too short")
}
out.MajorVersion = int(tokens[0].data[0])
out.MinorVersion = int(tokens[0].data[1])
out.BuildNumber = int(tokens[0].data[2])<<8 | int(tokens[0].data[3])
out.Version = fmt.Sprintf("%d.%d.%d", out.MajorVersion, out.MinorVersion, out.BuildNumber)
for _, tok := range tokens[1:] {
switch tok.token {
case plTokenEncryption:
if len(tok.data) > 0 {
out.Encryption = int(tok.data[0])
out.EncryptionMode = encryptionModeName(tok.data[0])
}
case plTokenInstOpt:
// 0x00 means the instance name matched (or none was requested).
out.InstanceMatches = len(tok.data) == 0 || tok.data[0] == 0
case plTokenMars:View on GitHub (pinned to 265b3a3dec)
Solutions
- Confirm the service is MSSQL with mssql.IsMssql or sqlcmd
- Hex-dump the reply; check the first entry is 00 xx xx 04 00 (token 0, length 4) and its offset lands inside the packet
- Compare with a known SQL Server's pre-login reply to spot the divergence
- Skip mssql fingerprinting for this target and use alternate detection
Defensive patterns
Strategy: try-catch
Validate before calling
if (!mssql.IsMssql(host, port)) { return; } Try / catch
try { const info = mssql.FingerprintMssql(host, port); }
catch (e) { if (String(e).includes('VERSION option too short')) log('malformed VERSION option: ' + host); else throw e; } Prevention
- Gate on IsMssql; a short VERSION payload is a malformed-reply signature
- Do not attempt credential attacks on hosts whose pre-login fails validation
When it happens
Trigger: mssql.FingerprintMssql / IsMssql against a reply whose first option is token 0x00 but declares length < 4 (or 0), so the version payload window is too small.
Common situations: Malformed emulators/honeypots; test fixtures with a VERSION option of length 0-3; desynchronized option tables where the first 5-byte entry is actually mid-data.
Related errors
- invalid PL option data range
- packet length mismatch: header=%d body=%d
- truncated PL option token
- missing PL option terminator
- no PL option tokens
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/72ee6d001f959f7e.
Report an issue: GitHub.