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.CView on GitHub (pinned to c37bfd9579)
Solutions
- Verify the delete URL uses the exact token and filename from the original upload.
- Check whether the file was already deleted or expired (purged) — if so there is nothing to delete.
- Re-upload if you still need a deletable object, and use the new token/deletionToken pair.
- 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
- Persist the exact token, filename and deletion token returned at upload time.
- Check for prior deletion/expiry before deleting programmatically.
- Treat DELETE 4xx as idempotent where possible.
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
- could not save metadata
- cannot find file %s/%s
- Could not delete file.
- File not found
- maxDownloads expired
AI-assisted analysis of dutchcoders/transfer.sh@c37bfd9579 (2026-09-05).
Data as JSON: /api/errors/61a4770fce17d01c.
Report an issue: GitHub.