AlistGo/alist · error · StorageNotFound

storage not found

Error message

storage not found

What it means

StorageNotFound is a sentinel in internal/errs/errors.go returned by op.GetStorageAndActualPath when no mounted storage's base path matches the requested virtual path. In AList every virtual path is served by a storage mounted at a base path, so failure to resolve the prefix means the path belongs to no storage. errs.IsNotFoundError treats it (and ObjectNotFound) as a not-found condition.

Source

Thrown at internal/errs/errors.go:19

package errs

import (
	"errors"
	"fmt"

	pkgerr "github.com/pkg/errors"
)

var (
	NotImplement = errors.New("not implement")
	NotSupport   = errors.New("not support")
	RelativePath = errors.New("access using relative path is not allowed")

	MoveBetweenTwoStorages = errors.New("can't move files between two storages, try to copy")
	UploadNotSupported     = errors.New("upload not supported")

	MetaNotFound     = errors.New("meta not found")
	StorageNotFound  = errors.New("storage not found")
	StreamIncomplete = errors.New("upload/download stream incomplete, possible network issue")
	StreamPeekFail   = errors.New("StreamPeekFail")

	UnknownArchiveFormat      = errors.New("unknown archive format")
	WrongArchivePassword      = errors.New("wrong archive password")
	DriverExtractNotSupported = errors.New("driver extraction not supported")
)

// NewErr wrap constant error with an extra message
// use errors.Is(err1, StorageNotFound) to check if err belongs to any internal error
func NewErr(err error, format string, a ...any) error {
	return fmt.Errorf("%w; %s", err, fmt.Sprintf(format, a...))
}

func IsNotFoundError(err error) bool {
	return errors.Is(pkgerr.Cause(err), ObjectNotFound) || errors.Is(pkgerr.Cause(err), StorageNotFound)
}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. List mounted storages (admin -> Storage) and confirm one base path is a prefix of your requested path
  2. Fix the mount path in the storage config or correct the request path to start with an existing base path
  3. Re-enable the disabled storage that owns the path
  4. If the storage was deleted intentionally, update clients/bookmarks to a path that still resolves

Example fix

// before
storage, actualPath, err := op.GetStorageAndActualPath("/old-mount/file.txt")

// after
storage, actualPath, err := op.GetStorageAndActualPath("/new-mount/file.txt")
if err != nil {
    if errors.Is(errors.Cause(err), errs.StorageNotFound) {
        // surface as 404, hint at mounted base paths
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// confirm some mounted storage covers the path before calling fs APIs
if _, err := fs.List(ctx, "/"); err != nil { return err }

Type guard

func isStorageNotFound(err error) bool {
    return err != nil && errs.IsNotFoundError(err)
}

Try / catch

storage, actualPath, err := op.GetStorageAndActualPath(p)
if err != nil {
    if isStorageNotFound(err) { /* 404: no storage mounted for this prefix */ }
    return err
}

Prevention

When it happens

Trigger: Any fs operation (list, get, put, other) whose path does not start with a mounted storage's base path: op.GetStorageAndActualPath("/nonexistent/dir/file") returns StorageNotFound. Also triggered when the matching storage is disabled or was deleted between requests.

Common situations: Typos in the mount path; storage removed or disabled in the admin panel while clients still cache old links; trailing-slash or case mismatch against the configured base path; fresh installs with zero storages mounted; API consumers hardcoding paths from another instance.

Related errors


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