navidrome/navidrome · error

Internal Server Error

Error message

Internal Server Error

What it means

GetTranscodeStream logs 'Error retrieving media file' and writes plain-text 'Internal Server Error' (HTTP 500) when api.ds.MediaFile(ctx).Get(mediaID) returns an error that is NOT model.ErrNotFound. The 404 path is reserved for missing records; any other failure (DB down, connection refused, context canceled, corruption) lands here.

Source

Thrown at server/subsonic/transcode.go:401

	transcodeParamsToken, err := p.String("transcodeParams")
	if err != nil {
		http.Error(w, "Bad Request", http.StatusBadRequest)
		return nil, nil
	}

	if !isValidMediaType(mediaType) {
		http.Error(w, "Bad Request", http.StatusBadRequest)
		return nil, nil
	}

	// Fetch the media file
	mf, err := api.ds.MediaFile(ctx).Get(mediaID)
	if err != nil {
		if errors.Is(err, model.ErrNotFound) {
			http.Error(w, "Not Found", http.StatusNotFound)
		} else {
			log.Error(ctx, "Error retrieving media file", "mediaID", mediaID, err)
			http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		}
		return nil, nil
	}

	// Validate the token and resolve streaming parameters
	streamReq, err := api.transcodeDecision.ResolveRequestFromToken(ctx, transcodeParamsToken, mf, p.IntOr("offset", 0))
	if err != nil {
		switch {
		case errors.Is(err, stream.ErrTokenInvalid), errors.Is(err, stream.ErrTokenStale):
			log.Warn(ctx, "Invalid or stale transcode token", "mediaID", mediaID, err)
			http.Error(w, "Gone", http.StatusGone)
		default:
			log.Error(ctx, "Error validating transcode params", err)
			http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		}
		return nil, nil
	}

View on GitHub (pinned to 4ed7494a32)

Solutions

  1. Check server logs for the accompanying 'Error retrieving media file' entry to see the underlying error
  2. Verify the database backend is reachable and healthy (DB connection settings, service status)
  3. For SQLite, ensure no other process holds a conflicting lock and the file is writable
  4. Check disk space and complete any pending schema migrations, then retry
Defensive patterns

Strategy: retry

Validate before calling

// Preflight: cheap health check of the server before batch streaming
resp, err := http.Get(serverURL + "/ping")
if err != nil || resp.StatusCode != 200 {
    return fmt.Errorf("server or database unavailable: %v", err)
}

Try / catch

resp, err := client.Get(url)
if err != nil { return err }
if resp.StatusCode == http.StatusInternalServerError {
    // transient server/DB failure: retry with backoff
    return retryWithBackoff(3, 2*time.Second, doStream)
}

Prevention

When it happens

Trigger: Database unavailable or restarting during a request; DB query fails (disk full, locked SQLite file, connection pool exhausted); request context canceled mid-query; schema mismatch after an incomplete upgrade.

Common situations: SQLite file locked by a backup process; Postgres container down; running the server while a migration is in flight; disk I/O errors on the DB volume.

Understand the failure class

Related errors


AI-assisted analysis of navidrome/navidrome@4ed7494a32 (2026-09-01). Data as JSON: /api/errors/454da000b4a88ab9. Report an issue: GitHub.