AlistGo/alist · error

user is not allowed to access via FTP

Error message

user is not allowed to access via FTP

What it means

Returned by FtpMainDriver.AuthUser when the authenticated user is either disabled or whose merged role permissions do not include the PermFTPAccess bit. Permission is computed with common.MergeRolePermissions over the user's roles, so the effective FTP permission is the union of role permissions scoped to BasePath.

Source

Thrown at server/ftp.go:136

	var err error
	if user == "anonymous" || user == "guest" {
		userObj, err = op.GetGuest()
		if err != nil {
			return nil, err
		}
	} else {
		userObj, err = op.GetUserByName(user)
		if err != nil {
			return nil, err
		}
		passHash := model.StaticHash(pass)
		if err = userObj.ValidatePwdStaticHash(passHash); err != nil {
			return nil, err
		}
	}
	perm := common.MergeRolePermissions(userObj, userObj.BasePath)
	if userObj.Disabled || !common.HasPermission(perm, common.PermFTPAccess) {
		return nil, errors.New("user is not allowed to access via FTP")
	}

	ctx := context.Background()
	ctx = context.WithValue(ctx, "user", userObj)
	if user == "anonymous" || user == "guest" {
		ctx = context.WithValue(ctx, "meta_pass", pass)
	} else {
		ctx = context.WithValue(ctx, "meta_pass", "")
	}
	ctx = context.WithValue(ctx, "client_ip", cc.RemoteAddr().String())
	ctx = context.WithValue(ctx, "proxy_header", d.proxyHeader)
	return ftp.NewAferoAdapter(ctx), nil
}

func (d *FtpMainDriver) GetTLSConfig() (*tls.Config, error) {
	if d.tlsConfig == nil {
		return nil, errors.New("TLS config not provided")
	}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. In the admin UI, edit the user's role(s) and enable the 'ftp access' permission (PermFTPAccess)
  2. Un-disable the user (user settings page) if Disabled is the cause
  3. Verify with an admin account that FTP works at all, confirming the server itself is healthy
  4. For anonymous/guest FTP, grant the permission to the guest user specifically
Defensive patterns

Strategy: validation

Validate before calling

// Before exposing FTP to a user, mirror the server's check
perm := common.MergeRolePermissions(userObj, userObj.BasePath)
if userObj.Disabled || !common.HasPermission(perm, common.PermFTPAccess) {
    return fmt.Errorf("deny FTP for %s: disabled or missing ftp access", userObj.Username)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "user is not allowed to access via FTP") {
    // surface a permission-fix hint to the admin instead of a generic auth failure
    return fmt.Errorf("FTP denied: enable 'ftp access' on the user's role or un-disable the account")
}

Prevention

When it happens

Trigger: FTP login (USER/PASS) with valid credentials where user.Disabled == true, or where none of the user's roles grant ftp access; also the guest/anonymous path when the guest user lacks the permission.

Common situations: FTP enabled in settings but the default role never got the 'ftp access' permission; a user was disabled for policy reasons but their FTP client still has saved credentials; after upgrading, roles were recreated without re-ticking the FTP permission.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/eb6efe86da6c9493. Report an issue: GitHub.