HelloZeroNet/ZeroNet · error · AnnounceError

Invalid response: %r

Error message

Invalid response: %r

What it means

After the UDP announce, poll_once() returned something, but it is neither None/empty nor a dict containing a "response" key. The plugin raises AnnounceError("Invalid response: %r") with the raw payload. This guards the shape of the decoded bencode UDP reply before reading back["response"]["peers"].

Source

Thrown at plugins/AnnounceBitTorrent/AnnounceBitTorrentPlugin.py:69

            raise AnnounceError("Udp trackers not available with proxies")

        ip, port = tracker_address.split("/")[0].split(":")
        tracker = UdpTrackerClient(ip, int(port))
        if helper.getIpType(ip) in self.getOpenedServiceTypes():
            tracker.peer_port = self.fileserver_port
        else:
            tracker.peer_port = 0
        tracker.connect()
        if not tracker.poll_once():
            raise AnnounceError("Could not connect")
        tracker.announce(info_hash=self.site.address_sha1, num_want=num_want, left=431102370)
        back = tracker.poll_once()
        if not back:
            raise AnnounceError("No response after %.0fs" % (time.time() - s))
        elif type(back) is dict and "response" in back:
            peers = back["response"]["peers"]
        else:
            raise AnnounceError("Invalid response: %r" % back)

        return peers

    def httpRequest(self, url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
            'Accept-Encoding': 'none',
            'Accept-Language': 'en-US,en;q=0.8',
            'Connection': 'keep-alive'
        }

        req = urllib.request.Request(url, headers=headers)

        if config.trackers_proxy == "tor":
            tor_manager = self.site.connection_server.tor_manager
            handler = sockshandler.SocksiPyHandler(socks.SOCKS5, tor_manager.proxy_ip, tor_manager.proxy_port)

View on GitHub (pinned to 454c0b2e7e)

Solutions

  1. Inspect the %r value in the message — if it contains an 'error' key, the tracker rejected the announce; read its reason.
  2. Verify the site's address_sha1/info_hash is valid and the tracker supports it.
  3. Use alternative trackers; drop trackers that consistently return invalid responses.
  4. Ensure the UDP socket is only receiving from the tracker (port conflicts).

Example fix

// before
else:
    raise AnnounceError("Invalid response: %r" % back)
// after
elif type(back) is dict and "error" in back:
    self.site.log.warning("Tracker error: %r" % back)
    return []
else:
    raise AnnounceError("Invalid response: %r" % back)
Defensive patterns

Strategy: type-guard

Type guard

def is_valid_announce_response(back):
    return isinstance(back, dict) and "response" in back and isinstance(back["response"], dict)

Try / catch

try:
    peers = announce_plugin.announceTrackerUdp(tracker_address, file_info)
except AnnounceError as e:
    log.warning("Invalid tracker reply: %s" % e)
    peers = []

Prevention

When it happens

Trigger: Tracker replies with an error packet (e.g. b'error': b'...'), a malformed/non-bencode datagram, or an intermediate device (captive portal, DPI box) sends junk UDP data that gets decoded into an unexpected object.

Common situations: Trackers rejecting announces with error messages (wrong info_hash, banned client); responses from a different socket/peer landing on the same port; corrupted datagrams on lossy networks.

Related errors


AI-assisted analysis of HelloZeroNet/ZeroNet@454c0b2e7e (2026-09-02). Data as JSON: /api/errors/e43049abff4555de. Report an issue: GitHub.