dutchcoders/transfer.sh · error
could not encode metadata
Error message
could not encode metadata
What it means
After incrementing the download counter, checkMetadata re-serializes the metadata to JSON and persists it back to storage. If json.Encoder fails to encode the in-memory metadata struct, this error is returned and the download is aborted. It indicates the metadata struct cannot be marshaled (essentially a programming/serialization invariant failure, since the struct is normally JSON-safe).
Source
Thrown at server/handlers.go:897
if err != nil {
return metadata, err
}
if err := json.NewDecoder(r).Decode(&metadata); err != nil {
return metadata, err
} else if metadata.MaxDownloads != -1 && metadata.Downloads >= metadata.MaxDownloads {
return metadata, errors.New("maxDownloads expired")
} else if !metadata.MaxDate.IsZero() && time.Now().After(metadata.MaxDate) {
return metadata, errors.New("maxDate expired")
} else if metadata.MaxDownloads != -1 && increaseDownload {
// todo(nl5887): mutex?
// update number of downloads
metadata.Downloads++
buffer := &bytes.Buffer{}
if err := json.NewEncoder(buffer).Encode(metadata); err != nil {
return metadata, errors.New("could not encode metadata")
} 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) {View on GitHub (pinned to c37bfd9579)
Solutions
- Inspect server logs for the underlying json error and check which metadata field fails to marshal.
- Ensure the metadata struct only contains JSON-serializable fields (no channels, funcs, or unsupported types).
- Re-upload the file to regenerate clean metadata.
- Update/patch the server build if a version change altered the metadata schema; consider logging the raw error instead of discarding it.
Example fix
// before
if err := json.NewEncoder(buffer).Encode(metadata); err != nil {
return metadata, errors.New("could not encode metadata")
}
// after
if err := json.NewEncoder(buffer).Encode(metadata); err != nil {
return metadata, fmt.Errorf("could not encode metadata: %w", err)
} Defensive patterns
Strategy: fallback
Try / catch
if err != nil && strings.Contains(err.Error(), "could not encode metadata") {
// retry download without relying on counter update, or report server bug
return retryDownload()
} Prevention
- Keep the metadata struct JSON-serializable when customizing the server.
- Test metadata round-trips (encode/decode) in unit tests after schema changes.
- Log the wrapped json error instead of discarding it.
When it happens
Trigger: checkMetadata with increaseDownload=true on a file with a finite MaxDownloads where json.NewEncoder(buffer).Encode(metadata) returns an error — practically only when the metadata struct holds an unmarshalable value (e.g. invalid field types or a corrupted in-memory state).
Common situations: Custom builds that added non-serializable fields to the metadata struct; metadata types changed between versions such that freshly decoded values cannot be re-encoded; corrupted metadata round-trips.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Could not encode metadata
- maxDownloads expired
- maxDate expired
- could not save metadata
- metadata doesn't exist
AI-assisted analysis of dutchcoders/transfer.sh@c37bfd9579 (2026-09-05).
Data as JSON: /api/errors/b098a61d3f9850c0.
Report an issue: GitHub.