{"record":{"id":"62ff141152023f6e","repo":"AlistGo/alist","slug":"user-is-not-allowed-to-access-via-sftp","errorCode":null,"errorMessage":"user is not allowed to access via SFTP","messagePattern":"user is not allowed to access via SFTP","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/sftp.go","lineNumber":84,"sourceCode":"\tctx = context.WithValue(ctx, \"client_ip\", sc.RemoteAddr().String())\n\tctx = context.WithValue(ctx, \"proxy_header\", d.proxyHeader)\n\treturn &sftp.DriverAdapter{FtpDriver: ftp.NewAferoAdapter(ctx)}, nil\n}\n\nfunc (d *SftpDriver) Close() {\n}\n\nfunc (d *SftpDriver) NoClientAuth(conn ssh.ConnMetadata) (*ssh.Permissions, error) {\n\tif conn.User() != \"guest\" {\n\t\treturn nil, errors.New(\"only guest is allowed to login without authorization\")\n\t}\n\tguest, err := op.GetGuest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpermGuest := common.MergeRolePermissions(guest, guest.BasePath)\n\tif guest.Disabled || !common.HasPermission(permGuest, common.PermFTPAccess) {\n\t\treturn nil, errors.New(\"user is not allowed to access via SFTP\")\n\t}\n\treturn nil, nil\n}\n\nfunc (d *SftpDriver) PasswordAuth(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {\n\tuserObj, err := op.GetUserByName(conn.User())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tperm := common.MergeRolePermissions(userObj, userObj.BasePath)\n\tif userObj.Disabled || !common.HasPermission(perm, common.PermFTPAccess) {\n\t\treturn nil, errors.New(\"user is not allowed to access via SFTP\")\n\t}\n\tpassHash := model.StaticHash(string(password))\n\tif err = userObj.ValidatePwdStaticHash(passHash); err != nil {\n\t\treturn nil, err\n\t}\n\treturn nil, nil","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/server/sftp.go#L66-L102","documentation":"Returned in SftpDriver.NoClientAuth's guest branch: the connecting user is 'guest' with none-auth, but the guest account is either disabled or its merged role permissions lack the FTP access bit (PermFTPAccess — SFTP deliberately reuses the FTP permission rather than having its own). The guest is resolved via op.GetGuest and checked with MergeRolePermissions before anonymous SFTP is allowed.","triggerScenarios":"Anonymous SFTP as guest when the guest user is disabled in the admin UI, or when the guest user's role does not include the 'ftp access' permission.","commonSituations":"SFTP enabled but guest permissions never configured; admin disabled the guest account to close anonymous access (this error is then the intended enforcement); fresh installs where the default role lacks ftp access.","solutions":["Grant the 'ftp access' permission to the guest user's role and re-enable the guest account (only if anonymous SFTP is desired)","If anonymous access should stay closed, connect with a real username/password instead","Verify with a real admin account that SFTP itself works before touching guest settings"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Mirror the server check before offering anonymous SFTP\nguest, _ := op.GetGuest()\nperm := common.MergeRolePermissions(guest, guest.BasePath)\nif guest.Disabled || !common.HasPermission(perm, common.PermFTPAccess) {\n    disableAnonymousSftp()\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"user is not allowed to access via SFTP\") {\n    // for guest none-auth: enable guest + ftp access permission, or switch to a real account\n}","preventionTips":["SFTP shares the FTP access permission bit — grant it to the guest role only if anonymous access is intended","Keep the guest account disabled when anonymous access is unwanted; this error is then correct behavior","Check the same permission whenever FTP behavior changes, since one bit governs both"],"tags":["sftp","auth","permissions","guest"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}