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
- List mounted storages (admin -> Storage) and confirm one base path is a prefix of your requested path
- Fix the mount path in the storage config or correct the request path to start with an existing base path
- Re-enable the disabled storage that owns the path
- 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
- Keep a validated allow-list of mount prefixes client-side
- Re-check storage configs after enabling/disabling mounts
- Return 404 for this sentinel so clients can stop retrying
- Automate a startup check that every expected base path resolves
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
- directory separator prohibited
- meta not found
- object not found
- {message}
- name token must come before chunk token
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/25a87ea628b6e0ed.
Report an issue: GitHub.