{"record":{"id":"50f451d60a55e862","repo":"shadow1ng/fscan","slug":"reply-rejected","errorCode":null,"errorMessage":"reply rejected","messagePattern":"reply rejected","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/nfs.go","lineNumber":139,"sourceCode":"\treply, err := readRPCFragment(conn, 4096)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(reply) < 24 {\n\t\treturn nil, fmt.Errorf(\"invalid reply\")\n\t}\n\n\treplyXID := binary.BigEndian.Uint32(reply[0:4])\n\tif replyXID != xid {\n\t\treturn nil, fmt.Errorf(\"xid mismatch\")\n\t}\n\tmsgType := binary.BigEndian.Uint32(reply[4:8])\n\tif msgType != 1 { // REPLY\n\t\treturn nil, fmt.Errorf(\"not a reply\")\n\t}\n\treplyStatus := binary.BigEndian.Uint32(reply[8:12])\n\tif replyStatus != 0 { // MSG_ACCEPTED\n\t\treturn nil, fmt.Errorf(\"reply rejected\")\n\t}\n\n\t// Skip auth verifier\n\toffset := 12\n\tif offset+8 > len(reply) {\n\t\treturn nil, fmt.Errorf(\"truncated\")\n\t}\n\t// verifier flavor + length\n\tverifierLen := binary.BigEndian.Uint32(reply[offset+4 : offset+8])\n\tif verifierLen > uint32(len(reply)-offset-8) {\n\t\treturn nil, fmt.Errorf(\"truncated verifier\")\n\t}\n\toffset += 8 + int(verifierLen)\n\tif pad := (4 - verifierLen%4) % 4; pad > 0 {\n\t\tif int(pad) > len(reply)-offset {\n\t\t\treturn nil, fmt.Errorf(\"truncated verifier padding\")\n\t\t}\n\t\toffset += int(pad)","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/nfs.go#L121-L157","documentation":"replyStatus (bytes 8-12) of an RPC REPLY indicates MSG_ACCEPTED (0) or MSG_DENIED (nonzero). getExports rejects denied replies. MSG_DENIED typically means RPC mismatch (program version unavailable), auth failure, or the server rejecting the call itself rather than the exported data being unavailable.","triggerScenarios":"Calling Scan or TestNFSGetExportsHandlesVerifierPadding against a server whose mountd replies MSG_DENIED — e.g. auth credentials rejected, RPC program/version mismatch, or GSS requirements.","commonSituations":"Server requires AUTH_SYS credentials the client did not supply; requesting the wrong mount protocol version (v1 vs v3); Kerberos-secured exports (sec=krb5) denying plain calls; firewalls/RPZ filters rejecting RPC.","solutions":["Check the server's export/auth requirements (/etc/exports, krb5 flags) and supply matching AUTH_SYS credentials","Verify the mount protocol version the server supports (mountd v1/v3) and send a matching request","Test manually with `showmount -e <host>` to see if the server denies RPC broadly","Ensure no IPS/firewall is blocking RPC replies"],"exampleFix":"// before\n// request with no auth flavor/credentials\n// after\n// use AUTH_SYS (flavor 1) with a valid uid/gid in the call's cred field\ncallCred := buildAuthSys(uid, gids, hostname)","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"exports, err := getExports(conn, xid)\nif err != nil && strings.Contains(err.Error(), \"reply rejected\") {\n    return fmt.Errorf(\"mountd denied RPC call (auth or version mismatch): %w\", err)\n}","preventionTips":["Match the server's auth flavor (AUTH_SYS vs RPCSEC_GSS) before calling","Use the mount protocol version the server advertises via portmapper","Test with showmount -e to confirm the host accepts plain RPC"],"tags":["network","rpc","nfs","auth"],"backgroundTag":"http-error-response","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}