shadow1ng/fscan · error

mssql: prelogin response missing encryption field

Error message

mssql: prelogin response missing encryption field

What it means

The prelogin response parsed successfully but did not include the ENCRYPT option (token 0x01), which the TDS spec requires in every prelogin response. Without it the library cannot determine the server's encryption preference for the subsequent Login7.

Source

Thrown at plugins/services/mssql_raw.go:165

func mssqlReadPrelogin(r io.Reader) error {
	packetType, payload, err := mssqlReadMessage(r)
	if err != nil {
		return err
	}
	if packetType != tdsPacketReply {
		return fmt.Errorf("mssql: invalid prelogin response packet type %d", packetType)
	}
	if len(payload) == 0 {
		return fmt.Errorf("mssql: empty prelogin response")
	}

	fields, err := mssqlParsePreloginFields(payload)
	if err != nil {
		return err
	}
	if _, ok := fields[tdsPreloginEncryption]; !ok {
		return fmt.Errorf("mssql: prelogin response missing encryption field")
	}
	return nil
}

func mssqlParsePreloginFields(payload []byte) (map[byte][]byte, error) {
	fields := make(map[byte][]byte)
	for pos := 0; ; pos += 5 {
		if pos >= len(payload) {
			return nil, fmt.Errorf("mssql: invalid prelogin option table")
		}
		token := payload[pos]
		if token == tdsPreloginTerminator {
			return fields, nil
		}
		if pos+5 > len(payload) {
			return nil, fmt.Errorf("mssql: truncated prelogin option")
		}
		offset := int(binary.BigEndian.Uint16(payload[pos+1 : pos+3]))

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Confirm the server is genuine Microsoft SQL Server; test with sqlcmd or go-mssqldb.
  2. If connecting through a TDS proxy/gateway, check it forwards the full prelogin response option table.
  3. If the endpoint is under your control, patch/upgrade the TDS implementation to include option 0x01.
  4. Capture the response packet and verify which prelogin options were actually returned.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the peer is real SQL Server before probing:
out, err := exec.Command("sqlcmd", "-S", host+","+fmt.Sprint(port), "-Q", "SELECT 1", "-l", "5").CombinedOutput()
if err != nil { /* not a healthy SQL Server */ }

Try / catch

_, err := mssqlRawLogin(ctx, host, port, user, pass, timeout)
if err != nil && strings.Contains(err.Error(), "missing encryption field") {
    // server/proxy sent incomplete prelogin; treat endpoint as non-standard TDS
}

Prevention

When it happens

Trigger: mssqlParsePreloginFields returns a map lacking key tdsPreloginEncryption (1) — the server omitted the encryption option from its option table.

Common situations: Non-Microsoft TDS implementations (e.g. FreeTDS-based gateways) with incomplete prelogin; corrupted or hand-crafted responses; very old or patched server builds.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/517aa2a2abbd3057. Report an issue: GitHub.