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

  1. Re-upload the missing file(s) and request the zip again.
  2. Check TTL/expiry settings and the storage backend to confirm which file was purged.
  3. List and GET the token's files individually to identify the missing one.
  4. 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

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


AI-assisted analysis of dutchcoders/transfer.sh@c37bfd9579 (2026-09-05). Data as JSON: /api/errors/255032b690cc4b82. Report an issue: GitHub.