HelloZeroNet/ZeroNet · error · VerifyError
Invalid json file: %s
Error message
Invalid json file: %s
What it means
verifyFile raises VerifyError('Invalid json file: %s') when a downloaded content.json cannot be parsed as UTF-8 JSON. The exception message embeds the underlying json.loads/json.load error. It means the file received from the peer is corrupt, truncated, or not JSON at all, so no further verification can proceed.
Source
Thrown at src/Content/ContentManager.py:943
return True # All good
# Verify file validity
# Return: None = Same as before, False = Invalid, True = Valid
def verifyFile(self, inner_path, file, ignore_same=True):
if inner_path.endswith("content.json"): # content.json: Check using sign
from Crypt import CryptBitcoin
try:
if type(file) is dict:
new_content = file
else:
try:
if sys.version_info.major == 3 and sys.version_info.minor < 6:
new_content = json.loads(file.read().decode("utf8"))
else:
new_content = json.load(file)
except Exception as err:
raise VerifyError("Invalid json file: %s" % err)
if inner_path in self.contents:
old_content = self.contents.get(inner_path, {"modified": 0})
# Checks if its newer the ours
if old_content["modified"] == new_content["modified"] and ignore_same: # Ignore, have the same content.json
return None
elif old_content["modified"] > new_content["modified"]: # We have newer
raise VerifyError(
"We have newer (Our: %s, Sent: %s)" %
(old_content["modified"], new_content["modified"])
)
if new_content["modified"] > time.time() + 60 * 60 * 24: # Content modified in the far future (allow 1 day+)
raise VerifyError("Modify timestamp is in the far future!")
if self.isArchived(inner_path, new_content["modified"]):
if inner_path in self.site.bad_files:
del self.site.bad_files[inner_path]
raise VerifyError("This file is archived!")
# Check sign
sign = new_content.get("sign")View on GitHub (pinned to 454c0b2e7e)
Solutions
- Re-download the content.json: delete the file locally (site data dir) so it is fetched again from a healthy peer
- Check the file on disk (data/<site>/content.json) — if truncated or HTML, the peer/transport is bad; try other peers
- Validate it manually with python -m json.tool data/<site>/content.json to see the exact JSON error
- Ensure the file is UTF-8 encoded; convert or re-save it if a tool wrote another encoding
Example fix
// before: serving a content.json edited by a tool that emitted invalid JSON
{"modified": 1500000000, "files": {"index.html": {"sha512": "abc"},,} }
// after: valid JSON
{"modified": 1500000000, "files": {"index.html": {"sha512": "abc"}}} Defensive patterns
Strategy: validation
Validate before calling
import json
def valid_json_file(path):
try:
with open(path, 'rb') as f:
json.loads(f.read().decode('utf8'))
return True
except (UnicodeDecodeError, ValueError):
return False Try / catch
from Content.ContentManager import VerifyError
try:
site.content_manager.isModified(inner_path, file)
except VerifyError as e:
if str(e).startswith('Invalid json file'):
redownload(inner_path) # delete file and fetch from other peers
else:
raise Prevention
- Always save content.json as UTF-8 without BOM
- Validate JSON with python -m json.tool before publishing
- Watch for peers serving HTML error pages instead of files
When it happens
Trigger: verifyFile is called by isModified while verifying an incoming content.json; the file body fails json.loads (Python <3.6 path decodes utf8 first, otherwise json.load reads the file object) and raises, which is re-raised as VerifyError.
Common situations: Truncated downloads from peers, a peer serving an HTML error page instead of content.json, wrong encoding (e.g. UTF-16 or BOM issues on old Python), or a locally corrupted data directory after an interrupted write.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Includes not allowed
- We have newer (Our: %s, Sent: %s)
- Modify timestamp is in the far future!
- This file is archived!
- Invalid signers_sign!
AI-assisted analysis of HelloZeroNet/ZeroNet@454c0b2e7e (2026-09-02).
Data as JSON: /api/errors/dcc3c271ecf8eb18.
Report an issue: GitHub.