{"record":{"id":"9f2f50b6bf01dbdf","repo":"AlistGo/alist","slug":"unknown-archive-format","errorCode":null,"errorMessage":"unknown archive format","messagePattern":"unknown archive format","errorType":"exception","errorClass":"UnknownArchiveFormat","httpStatus":null,"severity":"error","filePath":"internal/errs/errors.go","lineNumber":23,"sourceCode":"\t\"fmt\"\n\n\tpkgerr \"github.com/pkg/errors\"\n)\n\nvar (\n\tNotImplement = errors.New(\"not implement\")\n\tNotSupport   = errors.New(\"not support\")\n\tRelativePath = errors.New(\"access using relative path is not allowed\")\n\n\tMoveBetweenTwoStorages = errors.New(\"can't move files between two storages, try to copy\")\n\tUploadNotSupported     = errors.New(\"upload not supported\")\n\n\tMetaNotFound     = errors.New(\"meta not found\")\n\tStorageNotFound  = errors.New(\"storage not found\")\n\tStreamIncomplete = errors.New(\"upload/download stream incomplete, possible network issue\")\n\tStreamPeekFail   = errors.New(\"StreamPeekFail\")\n\n\tUnknownArchiveFormat      = errors.New(\"unknown archive format\")\n\tWrongArchivePassword      = errors.New(\"wrong archive password\")\n\tDriverExtractNotSupported = errors.New(\"driver extraction not supported\")\n)\n\n// NewErr wrap constant error with an extra message\n// use errors.Is(err1, StorageNotFound) to check if err belongs to any internal error\nfunc NewErr(err error, format string, a ...any) error {\n\treturn fmt.Errorf(\"%w; %s\", err, fmt.Sprintf(format, a...))\n}\n\nfunc IsNotFoundError(err error) bool {\n\treturn errors.Is(pkgerr.Cause(err), ObjectNotFound) || errors.Is(pkgerr.Cause(err), StorageNotFound)\n}\n\nfunc IsNotSupportError(err error) bool {\n\treturn errors.Is(pkgerr.Cause(err), NotSupport)\n}\nfunc IsNotImplement(err error) bool {","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/internal/errs/errors.go#L5-L41","documentation":"UnknownArchiveFormat is returned by the archive/decompression subsystem when it cannot detect the archive type of a file. AList inspects the file content (via stream peeking) to choose a decompress driver; if no registered format matches, this sentinel from internal/errs/errors.go is thrown.","triggerScenarios":"Calling the archive decompression API (/api/fs/archive or internal/fs/archive.go flows) on a file whose content is not a recognizable archive: a plain file, a corrupted archive, a wrong extension, or a format the bundled decompressor does not support.","commonSituations":"Renaming a non-archive to .zip/.tar; partially downloaded archives; proprietary or exotic compression formats; empty 0-byte files; self-extracting installers with prepended bytes that defeat content sniffing.","solutions":["Verify the file is a genuine, complete archive (test locally with unzip/tar/7z)","Re-download or repair the archive if truncated","Confirm the format is one AList's decompression drivers support (zip, tar variants, rar, 7z per compiled-in drivers)","Rename the file to its true extension so detection hints match the content"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// sniff magic bytes before invoking archive APIs\nhead := make([]byte, 8)\nif r, ok := src.(io.Reader); ok {\n    if _, err := io.ReadFull(r, head); err == nil {\n        switch {\n        case bytes.HasPrefix(head, []byte(\"PK\\x03\\x04\")): // zip\n        case bytes.HasPrefix(head, []byte(\"7z\\xbc\\xaf'\\x1c\")): // 7z\n        case bytes.HasPrefix(head, []byte(\"Rar!\")): // rar\n        default: return errs.UnknownArchiveFormat\n        }\n    }\n}","typeGuard":"func isUnknownArchiveFormat(err error) bool {\n    return err != nil && errors.Is(errors.Cause(err), errs.UnknownArchiveFormat)\n}","tryCatchPattern":"err := extract(ctx, src, dst)\nif isUnknownArchiveFormat(err) {\n    // tell the user the file is not a supported/valid archive; do not retry\n}","preventionTips":["Validate archive magic bytes before extraction","Test archives locally before hosting them","Keep extensions consistent with content","Reject 0-byte files before archive API calls"],"tags":["archive","decompression","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}