{"record":{"id":"17ebc9ba675b26f4","repo":"shadow1ng/fscan","slug":"accept-status-d","errorCode":null,"errorMessage":"accept status: %d","messagePattern":"accept status: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/nfs.go","lineNumber":166,"sourceCode":"\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)\n\t}\n\n\t// Accept status\n\tif offset+4 > len(reply) {\n\t\treturn nil, fmt.Errorf(\"truncated\")\n\t}\n\tacceptStatus := binary.BigEndian.Uint32(reply[offset : offset+4])\n\tif acceptStatus != 0 { // SUCCESS\n\t\treturn nil, fmt.Errorf(\"accept status: %d\", acceptStatus)\n\t}\n\toffset += 4\n\n\treturn p.parseExportList(reply[offset:]), nil\n}\n\nfunc (p *NFSPlugin) parseExportList(data []byte) []string {\n\tvar exports []string\n\toffset := 0\n\tfor offset+4 <= len(data) {\n\t\tvalueFollows := binary.BigEndian.Uint32(data[offset : offset+4])\n\t\toffset += 4\n\t\tif valueFollows == 0 {\n\t\t\tbreak\n\t\t}\n\t\tif offset+4 > len(data) {\n\t\t\tbreak\n\t\t}","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/nfs.go#L148-L184","documentation":"The RPC accept status must be SUCCESS (0); nonzero values are RPC protocol errors such as PROG_UNAVAIL, PROG_MISMATCH, PROC_UNAVAIL, GARBAGE_ARGS, or AUTH_ERROR. getExports surfaces the numeric status verbatim. The server received the call but refused it at the RPC program level — the export list was never produced.","triggerScenarios":"Calling Scan or TestNFSGetExportsHandlesVerifierPadding against a host whose mountd replies with a nonzero accept status — e.g. wrong mount program number/version in the request, or GARBAGE_ARGS from a malformed procedure payload.","commonSituations":"Requesting mount program 100005 v1 against a server that only supports v3; calling the wrong procedure number for EXPORT; server-side GSS-only configuration; GARBAGE_ARGS after a client encoding bug.","solutions":["Log/decode the status: 1=PROG_UNAVAIL, 2=PROG_MISMATCH, 3=PROC_UNAVAIL, 4=GARBAGE_ARGS, 5=AUTH_ERROR and fix accordingly","For PROG_MISMATCH, query portmapper for the supported mount protocol version and use it","For GARBAGE_ARGS, verify the EXPORT request body XDR encoding (procedure number 5, null args)","Confirm with `showmount -e <host>` whether a standard client succeeds"],"exampleFix":"// before\n// hardcoded: prog 100005, vers 1\n// after\n// negotiate version via portmapper GETPORT which returns the server's mountd version\nport, vers := portmapperGetPort(host, 100005)","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"exports, err := getExports(conn, xid)\nif err != nil {\n    var statusErr *AcceptStatusError\n    if errors.As(err, &statusErr) {\n        switch statusErr.Code {\n        case 2: return retryWithVersion(host, statusErr.LowVers)\n        case 4: return fmt.Errorf(\"GARBAGE_ARGS: check request encoding\")\n        default: return err\n        }\n    }\n}","preventionTips":["Decode the numeric accept status rather than treating all as generic failure","Negotiate the mount protocol version via portmapper","Validate request XDR encoding when seeing GARBAGE_ARGS"],"tags":["network","rpc","nfs","protocol"],"backgroundTag":"api-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"}