unslothai/unsloth · error · NativePathLeaseError
Native path grant secret is invalid.
Error message
Native path grant secret is invalid.
What it means
The lease secret found in the environment is not valid base64url — _b64decode(encoded) raised before any HMAC use. The secret must be base64url-encoded bytes; anything else (raw ASCII, standard base64 with '+'/'/', typos, quoted values) fails here.
Source
Thrown at studio/backend/utils/native_path_leases.py:272
def _decode_secret() -> bytes:
global _CACHED_LEASE_SECRET
if _CACHED_LEASE_SECRET is not None:
return _CACHED_LEASE_SECRET
with _SECRET_INIT_LOCK:
if _CACHED_LEASE_SECRET is not None:
return _CACHED_LEASE_SECRET
with _NATIVE_PATH_ENV_LOCK:
encoded = os.environ.get(LEASE_SECRET_ENV)
if encoded is None and _SCRUB_SAVED_SECRET is not None:
encoded = _SCRUB_SAVED_SECRET
if not encoded:
raise NativePathLeaseError("Native path grants require the managed desktop backend.")
try:
secret = _b64decode(encoded)
except Exception as exc:
raise NativePathLeaseError("Native path grant secret is invalid.") from exc
if len(secret) < _MIN_LEASE_SECRET_BYTES:
raise NativePathLeaseError("Native path grant secret is invalid.")
_CACHED_LEASE_SECRET = secret
return secret
def _split_lease(lease: str) -> tuple[str, str]:
if not isinstance(lease, str):
raise NativePathLeaseError("Native path grant has an invalid format.")
try:
lease.encode("ascii")
except UnicodeEncodeError as exc:
raise NativePathLeaseError("Native path grant has an invalid format.") from exc
parts = lease.split(".")
if len(parts) != 2 or not parts[0] or not parts[1]:
raise NativePathLeaseError("Native path grant has an invalid format.")
return parts[0], parts[1]
View on GitHub (pinned to 203007d190)
Solutions
- Regenerate the secret as base64url of at least 32 random bytes: openssl rand -base64 48 | tr '+/' '-_' | tr -d '=' and set that value.
- Make the signing side (Rust shell/dev harness) use the exact same encoded string.
- Remove surrounding quotes, whitespace, and newlines when setting the env var.
- Note the decode is unpadded-tolerant but urlsafe-alphabet-only — avoid '+' and '/' characters.
Example fix
# before export UNSLOTH_STUDIO_NATIVE_PATH_LEASE_SECRET='not-base64!!' # after export UNSLOTH_STUDIO_NATIVE_PATH_LEASE_SECRET="$(openssl rand -base64 48 | tr '+/' '-_' | tr -d '=')"
Defensive patterns
Strategy: validation
Validate before calling
import base64, os
def secret_env_ok() -> bool:
raw = os.environ.get("UNSLOTH_STUDIO_NATIVE_PATH_LEASE_SECRET")
if not raw:
return False
try:
return len(base64.urlsafe_b64decode(raw + "=" * (-len(raw) % 4))) >= 32
except Exception:
return False Prevention
- Generate secrets with a fixed recipe (openssl rand -base64 48 | tr '+/' '-_' | tr -d '=').
- Avoid .env files that wrap or quote long values; prefer direct env injection.
- Add a startup assertion that the secret decodes to >=32 bytes so misconfig fails at boot, not mid-request.
When it happens
Trigger: Setting UNSLOTH_STUDIO_NATIVE_PATH_LEASE_SECRET to a raw random string instead of base64url; including quotes or whitespace/newlines from shell or .env file interpolation; using standard base64 alphabet characters ('+', '/') that urlsafe decoding rejects; or a truncated copy-paste of the encoded value.
Common situations: Hand-rolling dev environments with openssl rand without base64 encoding; .env files that wrap long values across lines; YAML/JSON config that JSON-escapes the value differently; copy-paste from terminal output that inserted line breaks.
Related errors
- The executable at {binary} is not stable-diffusion.cpp: its
- GitHub token is required. Set it in the recipe config or the
- UNSLOTH_CPU_THREADS must be a positive integer
- Native path grants require the managed desktop backend.
- Add a Provider connection block before running this recipe.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/4864cd2879b80065.
Report an issue: GitHub.