dutchcoders/transfer.sh · error

metadata doesn't exist

Error message

metadata doesn't exist

What it means

checkDeletionToken (used by deleteHandler to authenticate deletes) first fetches the stored <filename>.metadata object. If storage reports the object does not exist (IsNotExist), the server returns this error. It means there is no metadata for the given token/filename, so the deletion request cannot be validated.

Source

Thrown at server/handlers.go:916

		} else if err := s.storage.Put(ctx, token, fmt.Sprintf("%s.metadata", filename), buffer, "text/json", uint64(buffer.Len())); err != nil {
			return metadata, errors.New("could not save metadata")
		}
	}

	return metadata, nil
}

func (s *Server) checkDeletionToken(ctx context.Context, deletionToken, token, filename string) error {
	s.lock(token, filename)
	defer s.unlock(token, filename)

	var metadata metadata

	r, _, err := s.storage.Get(ctx, token, fmt.Sprintf("%s.metadata", filename), nil)
	defer storage.CloseCheck(r)

	if s.storage.IsNotExist(err) {
		return errors.New("metadata doesn't exist")
	} else if err != nil {
		return err
	}

	if err := json.NewDecoder(r).Decode(&metadata); err != nil {
		return err
	} else if metadata.DeletionToken != deletionToken {
		return errors.New("deletion token doesn't match")
	}

	return nil
}

func (s *Server) purgeHandler() {
	ticker := time.NewTicker(s.purgeInterval)
	go func() {
		for {
			<-ticker.C

View on GitHub (pinned to c37bfd9579)

Solutions

  1. Verify the delete URL uses the exact token and filename from the original upload.
  2. Check whether the file was already deleted or expired (purged) — if so there is nothing to delete.
  3. Re-upload if you still need a deletable object, and use the new token/deletionToken pair.
  4. Inspect the storage backend to confirm whether <token>/<filename>.metadata exists; if the purger left orphaned data, clean it manually.

Example fix

// before
curl -X DELETE https://host/wrongtoken/file.txt -H 'X-Url-Delete: abc'
// after
curl -X DELETE https://host/<correct-token>/file.txt -H 'X-Url-Delete: <matching-deletion-token>'
Defensive patterns

Strategy: validation

Validate before calling

// confirm the object exists before issuing DELETE
resp, _ := http.Head(fmt.Sprintf("https://host/%s/%s", token, filename))
if resp.StatusCode == http.StatusNotFound {
	// nothing to delete; skip DELETE call
}

Try / catch

resp, err := doDelete(token, file, delToken)
if err == nil && resp.StatusCode != http.StatusOK {
	b, _ := io.ReadAll(resp.Body)
	if strings.Contains(string(b), "metadata doesn't exist") {
		// already gone or wrong token/filename; treat as idempotent success or fix URL
	}
}

Prevention

When it happens

Trigger: DELETE request with a deletion token for a token/filename combination whose .metadata object was never created (upload without metadata), already purged, or where the filename/token in the delete URL is wrong.

Common situations: Deleting a file uploaded by a transfer.sh version/flow that didn't write metadata; file already deleted or expired and purged; typo in token or filename in the delete URL; purger job removed the metadata but not the data.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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