GopeedLab/gopeed · error
unsupported ed2k link type
Error message
unsupported ed2k link type
What it means
parseLink (internal/protocol/ed2k/fetcher.go:402-412) parses the string with goed2k.ParseEMuleLink successfully, but the link's Type is not goed2k.LinkFile. The eMule link scheme covers more than files — server links (ed2k://|server|ip|port|/) and server-list links are valid links that this downloader cannot fetch, so they are rejected explicitly.
Source
Thrown at internal/protocol/ed2k/fetcher.go:409
func (fm *FetcherManager) Close() error {
fm.mu.Lock()
defer fm.mu.Unlock()
if fm.client != nil {
fm.client.Close()
fm.client = nil
}
return nil
}
func parseLink(raw string) (goed2k.EMuleLink, error) {
link, err := goed2k.ParseEMuleLink(raw)
if err != nil {
return goed2k.EMuleLink{}, err
}
if link.Type != goed2k.LinkFile {
return goed2k.EMuleLink{}, errors.New("unsupported ed2k link type")
}
return link, nil
}
func buildResource(link goed2k.EMuleLink) *base.Resource {
return &base.Resource{
Size: link.NumberValue,
Range: false,
Hash: link.Hash.String(),
Files: []*base.FileInfo{
{
Name: link.StringValue,
Size: link.NumberValue,
},
},
}
}
View on GitHub (pinned to 7b7327ffb3)
Solutions
- Use only file links: ed2k://|file|<name>|<size>|<md4-hex>|/
- Filter candidate links before task creation: require the segment after ed2k://| to be 'file'
- Surface a clear 'not a downloadable ed2k file link' message in UI instead of retrying
- Check link.StringValue/NumberValue exist after parse if you need extra safety
Example fix
// before
_, err := downloader.Resolve(&base.Request{URL: "ed2k://|server|10.0.0.1|4661|/"}, nil)
// after
isFile := func(u string) bool { return strings.HasPrefix(u, "ed2k://|file|") }
if !isFile(u) { return errors.New("only ed2k file links are supported") }
_, err := downloader.Resolve(&base.Request{URL: u}, nil) Defensive patterns
Strategy: validation
Validate before calling
func isEd2kFileLink(u string) bool {
return strings.HasPrefix(strings.ToLower(u), "ed2k://|file|")
}
if !isEd2kFileLink(u) { return fmt.Errorf("unsupported ed2k link (need |file|): %s", u) }
_, err := downloader.Resolve(&base.Request{URL: u}, nil) Type guard
func isEd2kFileLink(u string) bool { return strings.HasPrefix(strings.ToLower(u), "ed2k://|file|") } Try / catch
if _, err := downloader.Resolve(req, nil); err != nil {
if strings.Contains(err.Error(), "unsupported ed2k link type") {
// tell the user only ed2k file links are downloadable; filter the input
}
} Prevention
- Filter scraped/pasted ed2k links to the |file| variant before task creation
- Validate links client-side (prefix check) for a friendlier message
- Remember server and server-list links parse fine but are never fetchable here
When it happens
Trigger: Creating/resolving a task with an ed2k server link (ed2k://|server|207.62.153.10|4242|/) or server-list link instead of a file link; paste/clipboard bugs that grab the wrong link from a page of mixed ed2k links; parsing the 'file' variant with malformed segments such that goed2k still classifies it as a non-file type.
Common situations: Users pasting a server link copied from an eMule server list; indexers that return multiple ed2k link kinds; scripts iterating over ed2k:// URLs scraped from a page without filtering by the |file| segment.
Related errors
- invalid blob url
- cannot change ed2k link after transfer started
- NAVIGATION_FAILED
- invalid blob options
- cannot change ed2k target path after transfer started
AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16).
Data as JSON: /api/errors/7354662598d1713b.
Report an issue: GitHub.