Skip to main content

Troubleshooting

The dist won't import / "bad marshal data"

The protected dist was almost certainly built with a different CPython version than the one running it. The marshal/bytecode format is version-specific. Rebuild with the same Python version you ship for, and make sure Obfy is installed into that interpreter.

obfy build can't import the runtime

obfy build needs the bundled runtime importable from the --python you pass. Make sure Obfy is installed into that interpreter (the runtime ships with the obfy package):

python -m pip install obfy   # using the same interpreter you pass to --python

Code breaks only at --level 4

Level 4 renames public names across the whole tree, which breaks code that looks names up dynamically (by string, getattr, or framework auto-discovery). Exclude the affected files so they stay as plain source, or drop to --level 3:

obfy build --src ./app --out ./dist --level 4 --exclude "*/plugins/*"

See Excluding files.

The dist refuses to run

If you built with --license, the runtime enforces its terms locally. Common causes:

  • Expired — the expires date has passed (and anti_rollback blocks clock tricks).
  • Wrong machine — a machines, hostnames, or disks binding doesn't match the current host.
  • Anti-debug — built with --anti-debug and a tracer/debugger is attached.
  • Anti-tamper — built with --anti-tamper and the on-disk loader or manifest.json was modified.

A secret (.env, key) ended up in the dist

Every non-.py file under --src is copied into the dist. Point --src at your code package rather than your repo root, or build from a code-only staging tree.

I can't run obfy build — not authorized

Your machine isn't authorized, or you're out of seats. Run obfy login and obfy register to claim a seat slot (logging in alone isn't enough), then check obfy whoami. Revoke an unused device from the portal's Devices page if you've hit the per-seat machine limit. On an air-gapped machine, authorize with an offline activation (obfy register --offlineobfy activate <file>) instead. See Seats and devices.