HelloZeroNet/ZeroNet · error · VerifyError

This file is archived!

Error message

This file is archived!

What it means

verifyFile raises VerifyError('This file is archived!') when isArchived(inner_path, new_content['modified']) returns True — i.e. the site owner previously published an 'archive' entry for this inner_path with a modified timestamp at or after the incoming content's timestamp. Archived files are permanently frozen: any update with an older-or-equal timestamp is rejected, protecting against re-activation of revoked content (commonly user content/joined certs).

Source

Thrown at src/Content/ContentManager.py:959

                            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")
                signs = new_content.get("signs", {})
                if "sign" in new_content:
                    del(new_content["sign"])  # The file signed without the sign
                if "signs" in new_content:
                    del(new_content["signs"])  # The file signed without the signs

                sign_content = json.dumps(new_content, sort_keys=True)  # Dump the json to string to remove whitepsace

                # Fix float representation error on Android
                modified = new_content["modified"]
                if config.fix_float_decimals and type(modified) is float and not str(modified).endswith(".0"):
                    modified_fixed = "{:.6f}".format(modified).strip("0.")
                    sign_content = sign_content.replace(
                        '"modified": %s' % repr(modified),
                        '"modified": %s' % modified_fixed
                    )

View on GitHub (pinned to 454c0b2e7e)

Solutions

  1. If you are the archived user: you cannot republish this path; obtain a new cert/identity or ask the site owner to remove the archive entry
  2. If you are the site owner and archived by mistake: remove the path from the 'archives' section of the root content.json, re-sign and publish
  3. Ensure you publish a new content with modified timestamp greater than the archive timestamp only if the archive rule allows it (archives typically block all newer content too — owner action is required)

Example fix

// before (root content.json blocking the path)
{"archive": {"users/1ABC/content.json": 1600000000}}
// after (owner un-archives)
{"archive": {}, ...}  // re-sign and publish
Defensive patterns

Strategy: try-catch

Validate before calling

import json
root = json.load(open('data/<site>/content.json'))
new = json.load(open('my_content.json'))
arch = root.get('archive', {})
blocked = [p for p, ts in arch.items() if p == 'users/<addr>/content.json' and ts >= new.get('modified', 0)]
if blocked:
    raise ValueError('path is archived by site owner')

Try / catch

from Content.ContentManager import VerifyError
try:
    site.content_manager.isModified(inner_path, file)
except VerifyError as e:
    if str(e) == 'This file is archived!':
        stop_publishing(inner_path)  # path is permanently frozen by owner
    else:
        raise

Prevention

When it happens

Trigger: isModified -> verifyFile passes the future-timestamp check, then isArchived finds an entry in the root content.json's 'archives' (or cloned archives) covering this path with modified >= the new content's modified; bad_files entry for the path is deleted before raising.

Common situations: A user whose content was archived (banned/revoked) keeps trying to republish the same content.json; a site owner archived a path and peers reject the old revision; replaying an old pre-archive content.json after a rollback attempt.

Related errors


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