{"record":{"id":"7c710d5eb8139c75","repo":"HelloZeroNet/ZeroNet","slug":"announce-onion-address-to-failed-s","errorCode":null,"errorMessage":"Announce onion address to failed: %s","messagePattern":"Announce onion address to failed: (.+?)","errorType":"exception","errorClass":"AnnounceError","httpStatus":null,"severity":"error","filePath":"plugins/AnnounceZero/AnnounceZeroPlugin.py","lineNumber":130,"sourceCode":"            site_index += 1\n\n        # Check if we need to sign prove the onion addresses\n        if \"onion_sign_this\" in res:\n            self.site.log.debug(\"Signing %s for %s to add %s onions\" % (res[\"onion_sign_this\"], tracker_address, len(sites)))\n            request[\"onion_signs\"] = {}\n            request[\"onion_sign_this\"] = res[\"onion_sign_this\"]\n            request[\"need_num\"] = 0\n            for site in sites:\n                onion = self.site.connection_server.tor_manager.getOnion(site.address)\n                publickey = self.site.connection_server.tor_manager.getPublickey(onion)\n                if publickey not in request[\"onion_signs\"]:\n                    sign = CryptRsa.sign(res[\"onion_sign_this\"].encode(\"utf8\"), self.site.connection_server.tor_manager.getPrivatekey(onion))\n                    request[\"onion_signs\"][publickey] = sign\n            res = tracker_peer.request(\"announce\", request)\n            if not res or \"onion_sign_this\" in res:\n                if full_announce:\n                    time_full_announced[tracker_address] = 0\n                raise AnnounceError(\"Announce onion address to failed: %s\" % res)\n\n        if full_announce:\n            tracker_peer.remove()  # Close connection, we don't need it in next 5 minute\n\n        self.site.log.debug(\n            \"Tracker announce result: zero://%s (sites: %s, new peers: %s, add: %s, mode: %s) in %.3fs\" %\n            (tracker_address, site_index, peers_added, add_types, mode, time.time() - s)\n        )\n\n        return True\n","sourceCodeStart":112,"sourceCodeEnd":141,"githubUrl":"https://github.com/HelloZeroNet/ZeroNet/blob/454c0b2e7e000fda7000cba49027541fbf327b96/plugins/AnnounceZero/AnnounceZeroPlugin.py#L112-L141","documentation":"After the initial announce, zero trackers may reply with \"onion_sign_this\" asking the client to prove ownership of its onion address by signing a nonce. The plugin signs with the Tor manager's private key and re-requests announce. If the second response is empty or again contains \"onion_sign_this\", AnnounceError(\"Announce onion address to failed: %s\") is raised — the onion authentication handshake failed.","triggerScenarios":"Tor manager is unavailable or getPrivatekey(onion) returns None so the sign is missing/invalid; the tracker rejects the RSA signature; the tracker keeps demanding re-signing (nonce/protocol mismatch); the second request times out returning None.","commonSituations":"ZeroNet running without Tor or without control port access so the onion private key can't be fetched; tracker with onion-signature verification enabled and client's CryptRsa output mismatched; version drift between client and tracker announce protocol.","solutions":["Ensure Tor is running and TorController/control port is configured so getPrivatekey(onion) returns a valid key.","Check the tracker's response in the error for its rejection reason.","Retry — the failed tracker will be full-announced again next cycle.","Disable onion announcement (no onion address) if Tor isn't available.","Update ZeroNet client and tracker to matching protocol versions."],"exampleFix":"// before\nsign = CryptRsa.sign(res[\"onion_sign_this\"].encode(\"utf8\"), self.site.connection_server.tor_manager.getPrivatekey(onion))\n// after\nprivatekey = self.site.connection_server.tor_manager.getPrivatekey(onion)\nif not privatekey:\n    raise AnnounceError(\"Cannot sign onion challenge: no private key for %s (Tor not available?)\" % onion)\nsign = CryptRsa.sign(res[\"onion_sign_this\"].encode(\"utf8\"), privatekey)","handlingStrategy":"try-catch","validationCode":"if not self.site.connection_server.tor_manager or not self.site.connection_server.tor_manager.getPrivatekey(onion):\n    skip_onion_signing = True  # don't attempt onion announce without a key","typeGuard":"def can_sign_onion(tor_manager, onion):\n    return bool(tor_manager and tor_manager.getPrivatekey(onion))","tryCatchPattern":"try:\n    peers = announce_plugin.announceTrackerZero(tracker_address, file_info, *args)\nexcept AnnounceError as e:\n    if \"onion\" in str(e):\n        log.warning(\"Onion sign challenge failed (Tor available?): %s\" % e)\n    else:\n        raise","preventionTips":["Ensure Tor is running with ControlPort and cookie/password auth configured","Skip onion announces when the client has no onion private key","Keep CryptRsa and tracker verification logic version-matched","Retry the announce; the challenge is re-issued next cycle"],"tags":["network","tor","onion","zeronet","authentication"],"backgroundTag":"onion-signature-verification-failed","analyzedSha":"454c0b2e7e000fda7000cba49027541fbf327b96","analyzedAt":"2026-09-02T19:46:57.278Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}