shadow1ng/fscan · error

truncated verifier padding

Error message

truncated verifier padding

What it means

XDR pads opaque verifier data to a 4-byte boundary. After skipping the verifier, getExports checks that the padding bytes are present in the reply; if not, the record is truncated and the accept-status field can't be read safely. This is the padding-specific sibling of the "truncated verifier" check (a known corner case exercised by TestNFSGetExportsHandlesVerifierPadding).

Source

Thrown at plugins/services/nfs.go:155

	replyStatus := binary.BigEndian.Uint32(reply[8:12])
	if replyStatus != 0 { // MSG_ACCEPTED
		return nil, fmt.Errorf("reply rejected")
	}

	// Skip auth verifier
	offset := 12
	if offset+8 > len(reply) {
		return nil, fmt.Errorf("truncated")
	}
	// verifier flavor + length
	verifierLen := binary.BigEndian.Uint32(reply[offset+4 : offset+8])
	if verifierLen > uint32(len(reply)-offset-8) {
		return nil, fmt.Errorf("truncated verifier")
	}
	offset += 8 + int(verifierLen)
	if pad := (4 - verifierLen%4) % 4; pad > 0 {
		if int(pad) > len(reply)-offset {
			return nil, fmt.Errorf("truncated verifier padding")
		}
		offset += int(pad)
	}

	// Accept status
	if offset+4 > len(reply) {
		return nil, fmt.Errorf("truncated")
	}
	acceptStatus := binary.BigEndian.Uint32(reply[offset : offset+4])
	if acceptStatus != 0 { // SUCCESS
		return nil, fmt.Errorf("accept status: %d", acceptStatus)
	}
	offset += 4

	return p.parseExportList(reply[offset:]), nil
}

func (p *NFSPlugin) parseExportList(data []byte) []string {

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Retry against the host to rule out transient truncation
  2. Verify with showmount -e whether the server is generally functional
  3. Flag the host as non-conformant (missing XDR padding) and continue scanning
  4. Capture the raw reply and compare against a known-good mountd EXPORT reply

Example fix

// before
// server omits padding after an 11-byte verifier
// after
// pad-tolerant fallback: treat missing final padding as end-of-reply
if pad > 0 && int(pad) > len(reply)-offset {
    // tolerate missing trailing pad only if no further data expected
}
Defensive patterns

Strategy: fallback

Validate before calling

null

Type guard

null

Try / catch

exports, err := getExports(conn, xid)
if err != nil && strings.Contains(err.Error(), "truncated verifier padding") {
    // tolerate non-conformant servers missing trailing XDR pad
    exports, err = getExportsLenient(conn, xid)
}

Prevention

When it happens

Trigger: Calling Scan or TestNFSGetExportsHandlesVerifierPadding when the reply ends exactly at verifierLen with fewer than (4 - verifierLen%4)%4 padding bytes remaining.

Common situations: Server implementations that omit XDR padding (a spec bug); truncated last TCP segment; crafted replies from fuzzed targets.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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