dutchcoders/transfer.sh · error
File not found
Error message
File not found
What it means
zipHandler iterates the keys under an archive token and calls s.storage.Get for each file. When Get returns a not-exist error, the handler responds with HTTP 404 'File not found'. One of the files listed under the token is missing from the storage backend.
Source
Thrown at server/handlers.go:995
zw := zip.NewWriter(w)
for _, key := range strings.Split(files, ",") {
key = resolveKey(key, s.proxyPath)
token := strings.Split(key, "/")[0]
filename := sanitize(strings.Split(key, "/")[1])
if _, err := s.checkMetadata(r.Context(), token, filename, true); err != nil {
s.logger.Printf("Error metadata: %s", err.Error())
continue
}
reader, _, err := s.storage.Get(r.Context(), token, filename, nil)
defer storage.CloseCheck(reader)
if err != nil {
if s.storage.IsNotExist(err) {
http.Error(w, "File not found", 404)
return
}
s.logger.Printf("%s", err.Error())
http.Error(w, "Could not retrieve file.", http.StatusInternalServerError)
return
}
header := &zip.FileHeader{
Name: strings.Split(key, "/")[1],
Method: zip.Store,
Modified: time.Now().UTC(),
}
fw, err := zw.CreateHeader(header)
if err != nil {View on GitHub (pinned to c37bfd9579)
Solutions
- Re-upload the missing file(s) and request the zip again.
- Check TTL/expiry settings and the storage backend to confirm which file was purged.
- List and GET the token's files individually to identify the missing one.
- Avoid racing delete operations against active archive downloads.
Example fix
// before
reader, _, err := s.storage.Get(r.Context(), token, filename, nil)
if err != nil {
if s.storage.IsNotExist(err) {
http.Error(w, "File not found", 404)
// after
reader, _, err := s.storage.Get(r.Context(), token, filename, nil)
if err != nil {
if s.storage.IsNotExist(err) {
s.logger.Printf("zip: missing %s/%s", token, filename)
http.Error(w, "File not found: "+filename, 404) Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight each file in the archive token before requesting the zip:
for _, f := range files {
resp, err := http.Head(baseURL + "/" + token + "/" + f)
if err != nil || resp.StatusCode == 404 {
// f is missing — re-upload before zipping
}
} Try / catch
// Treat 404 as 'file missing from token': identify which file, re-upload, retry
if resp.StatusCode == 404 { reuploadMissingFile(); retryArchiveDownload() } Prevention
- Set TTLs longer than the expected lifetime of archive tokens.
- Disable or align cleanup cron jobs with active download windows.
- Avoid deleting files while an archive download of the token is in flight.
- Download files individually first to detect missing objects before zipping.
When it happens
Trigger: s.storage.Get returns an error for which s.storage.IsNotExist(err) is true while building the zip: a file listed in the token's key set was deleted, expired via TTL, or never fully persisted.
Common situations: A file expired (TTL elapsed) between listing and fetching; local storage directory cleaned by a cron job; one file in a multi-file upload failed to persist; race between a concurrent delete and the zip download.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- metadata doesn't exist
- cannot find file %s/%s
- could not save metadata
- Could not save metadata
- Could not delete file.
AI-assisted analysis of dutchcoders/transfer.sh@c37bfd9579 (2026-09-05).
Data as JSON: /api/errors/255032b690cc4b82.
Report an issue: GitHub.